﻿/* css/tokens.css */
:root {
  --coreo-bg-base: #050508;
  --coreo-bg-secondary: #151517;
  --coreo-surface-raised: #3C3C40;
  /* v0.9.0：兩關色彩完全分離，避免單關調色污染另一關 */
  --coreo-s1-path: #202936;
  --coreo-s1-path-metal: #304055;
  --coreo-s1-wall-top: #040506;
  --coreo-s1-wall-side: #182230;
  --coreo-s1-wall-shadow: rgba(1, 5, 10, 0.3);
  --coreo-s1-shell: #DCE8F5;
  --coreo-s1-shell-hot: #F6FBFF;
  --coreo-s1-guide: #008CFF;
  --coreo-s1-guide-secondary: #42C8FF;
  --coreo-s1-highlight: #DDF7FF;
  --coreo-s1-core-basic: #EAFBFF;
  --coreo-s1-core-boost: #0878FF;
  --coreo-s2-path: #1D2634;
  --coreo-s2-path-metal: #2A3A52;
  --coreo-s2-wall-top: #03050A;
  --coreo-s2-wall-side: #172338;
  --coreo-s2-wall-shadow: rgba(1, 5, 12, 0.32);
  --coreo-s2-shell: #C9D8EA;
  --coreo-s2-shell-hot: #EFF7FF;
  --coreo-s2-guide: #2F63FF;
  --coreo-s2-guide-secondary: #73B7FF;
  --coreo-s2-tip: #9EDCFF;
  --coreo-s2-highlight: #E5F3FF;
  --coreo-s2-core-basic: #EDF9FF;
  --coreo-s2-core-boost: #00D6C7;
  --coreo-s2-core-boost-soft: #72F2E5;

  --coreo-path: var(--coreo-s1-path);
  --coreo-path-edge: var(--coreo-s1-path-metal);
  --coreo-path-glass: rgba(212, 240, 255, 0.11);
  --coreo-path-glass-hot: rgba(0, 230, 255, 0.42);
  --coreo-wall-side: var(--coreo-s1-wall-side);
  --coreo-wall-face: var(--coreo-s1-wall-top);
  --coreo-edge-highlight: rgba(255, 255, 255, 0.22);
  --coreo-matrix-glow: rgba(0, 229, 255, 0.05);
  /* v0.6.9：矩陣線條回歸——Sean 指定找回 v0.5.19 的「迷宮接縫矩陣點亮」效果，但顏色改白金非舊金黃，
     跟 Supernova Burst 疊加觸發，不取代它。見 .cell.path::after／.cell.wall::before 與 #world.matrix-pulse */
  --coreo-matrix-glow-platinum: rgba(244, 248, 255, 0.9);
  --coreo-matrix-glow-platinum-soft: rgba(100, 210, 255, 0.32);
  --coreo-text-primary: #F4F5F8;
  --coreo-text-secondary: #8DA9C4;
  --coreo-glow-core: #00E6FF;
  --coreo-glow-hot: #64D2FF;
  --coreo-credit: #00E6FF;
  /* v0.5.24：GPT/GEM 裁決，Core Shard 改用淡冰藍，跟主角冰藍色系更貼近 */
  --coreo-core-basic: var(--coreo-s1-core-basic);
  --coreo-core-basic-glow: #64D2FF;
  --coreo-core-boost: var(--coreo-s1-core-boost);
  --coreo-core-boost-deep: #F4F8FF;
  --coreo-stage-secured: #00E6FF;
  /* v0.5.24：主角走過路徑的短暫餘光（動能軌跡 Trail），低調、快速消退，不是可收集物 */
  --coreo-trail: #D4F0FF;
  --coreo-path-rim: rgba(0, 229, 255, 0.18);
  --coreo-path-inner-glow: rgba(245, 245, 247, 0.06);
  --coreo-wall-edge-highlight: rgba(255, 255, 255, 0.08);
  --coreo-actor-villain-guard: #C1121F;
  --coreo-actor-villain-guard-glow: rgba(193, 18, 31, 0.45);
  --coreo-core-burst: #FF007F;
  --coreo-core-guide: #FFFFFF;
  --coreo-core-key: #9D00FF;
  --coreo-credit-hot: #FF007F;
  /* v0.5.24：GPT/GEM 裁決，EMBER/危險色從霓虹紅粉改為熔岩橘紅，暖化壓迫感、降低暗黑重的偏冷電光感 */
  --coreo-danger: #FF453A;
  --coreo-enemy-red: #FF453A;
  --coreo-enemy-red-orange: #FF453A;
  --coreo-danger-glow: #FFD1D8;
  --coreo-threat-dark: #7A1024;
  --coreo-special-violet: #9D00FF;
  --coreo-success: #30D158;
  --coreo-gesture-safe-inset: 48px;

  /* v0.6：Stage 02 專屬牆體色（獨立於 Stage01 的 --coreo-wall-face，兩關可各自調整） */
  --coreo-wall-face-s2: var(--coreo-s2-wall-top);
  /* v0.6：Edge Lighting 牆體邊緣動態光效脈衝色 */
  --coreo-edge-basic: rgba(212, 240, 255, 0.8);
  /* v0.6.7：不再用金色，Core Pulse 拾取瞬間改走 Supernova Burst 的白/青系（見 .supernova-burst-fx） */
  --coreo-edge-pulse: rgba(0, 240, 255, 0.75);
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

html,
body {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  min-height: 100%;
  /* v0.5.19：牆體改冷藍灰後，原本的警戒環境光相對變搶戲，降低強度壓回去 */
  /* v0.5.24：環境光色相隨 EMBER 改為熔岩橘紅，強度維持低調，不整體調亮 */
  background:
    radial-gradient(circle at 50% 12%, rgba(0, 229, 255, 0.17), transparent 34%),
    radial-gradient(circle at 82% 36%, rgba(255, 69, 58, 0.06), transparent 22%),
    linear-gradient(180deg, #151517 0%, var(--coreo-bg-base) 48%, #070708 100%);
  color: var(--coreo-text-primary);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  overscroll-behavior: none;
  overscroll-behavior-x: none;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}

body {
  -webkit-overflow-scrolling: auto;
}

/* v0.9.3 Stage02：移除上方大面積青／紅環境暈染，保留乾淨的深黑藍空間與 HUD 對比。 */
body.stage-02-active {
  background: linear-gradient(180deg, #090D14 0%, #050810 44%, #04060A 100%);
}

body.stage-02-active #fog-overlay {
  height: 14%;
  background: linear-gradient(to bottom, rgba(6, 9, 15, 0.86) 0%, rgba(6, 9, 15, 0.22) 68%, transparent 100%);
}

/* =========================================
   HUD (極簡化，專注 Light Core 收集)
========================================= */
#hud {
  position: fixed;
  top: max(env(safe-area-inset-top), 16px);
  left: max(env(safe-area-inset-left), 20px);
  right: max(env(safe-area-inset-right), 20px);
  display: flex;
  justify-content: space-between;
  z-index: 1000;
  pointer-events: none;
}

.hud-group {
  display: flex;
  flex-direction: column;
}

.hud-label {
  font-size: 10px;
  color: var(--coreo-text-secondary);
  letter-spacing: 1px;
  margin-bottom: 2px;
}

.hud-value {
  font-size: 20px;
  font-weight: 650;
  color: var(--coreo-text-primary);
  transition: transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.hud-value.glow {
  color: var(--coreo-s1-guide);
  text-shadow: 0 0 16px rgba(0, 230, 255, 0.72);
  transform: scale(1.2);
}

/* v0.8.3：Sean/GPT 最高優先覆蓋裁決——HUD 是 #world 的手足節點不是子節點，沒辦法用
   .stage-02 後代選擇器涵蓋，改由 js/main.js 的 flashHud() 依 currentStage 切換 class 名稱。
   Stage01 沿用上面的 .glow（黃綠閃光），Stage02 改用這個冷白/冰青版本 */
.hud-value.glow-s2 {
  color: #F4F8FF;
  text-shadow: 0 0 16px rgba(0, 240, 255, 0.76);
  transform: scale(1.2);
}

#version-tag {
  position: fixed;
  bottom: max(env(safe-area-inset-bottom), 8px);
  left: max(env(safe-area-inset-left), 8px);
  font-size: 9px;
  letter-spacing: 0.05em;
  color: var(--coreo-text-secondary);
  opacity: 0.5;
  z-index: 1000;
  pointer-events: none;
}

/* =========================================
   3D 視圖與深度渲染
========================================= */
#game-container {
  position: fixed;
  inset: 0;
  perspective: 1280px;
  perspective-origin: 50% 54%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}

/* v0.6.4：過關放大脫離動畫如果往下飄（Stage02 出口在下），可用的畫面空間比往上飄少
   （鏡頭錨點固定在畫面 56% 高度，下方只剩約 44% 空間），原本的 overflow:hidden 會把往下
   飄的放大特效直接裁掉，看起來像效果消失。遊戲在觸發過關的當下就已經停止主迴圈，
   之後只會走向重新整理，這裡放寬 overflow 不會影響任何操控判定 */
#game-container.victory-clear,
#camera-rig.victory-clear,
#world.victory-clear {
  overflow: visible;
}

/* v0.6.7：#world 另外有 contain: layout paint style（camera.js 效能優化用），
   其中 contain:paint 會獨立把超出 #world 自己邊界的子元素裁掉，跟 overflow 屬性無關。
   過關當下主迴圈已停止，之後只會走向重新整理，解除 contain 不影響任何效能判斷。
   （CX 後續改用 fixed 定位的 victory-player-clone 播放過關放大，已不受這層裁切影響，
   但這裡還是保留修正，避免其他還留在 #world 內的過關視覺元素被裁到） */
#world.victory-clear {
  contain: none;
}

#fog-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 18%;
  background: linear-gradient(to bottom, rgba(21, 21, 23, 0.94) 0%, rgba(21, 21, 23, 0.34) 62%, transparent 100%);
  z-index: 500;
  pointer-events: none;
}

#camera-rig {
  transform-style: preserve-3d;
  width: 100%;
  height: 100%;
  position: absolute;
  overflow: hidden;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}

#world {
  transform-style: preserve-3d;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: rotateX(40deg) translateZ(-165px);
  transition: none;
  will-change: transform;
  backface-visibility: hidden;
  contain: layout paint style;
  /* v0.5.21：深空玻璃底盤——整塊迷宮懸浮在透明玻璃板上，只用透明底色＋邊框做出反光邊緣，
     刻意不用 backdrop-filter（會隨鏡頭捲動持續做模糊取樣，Android 效能風險高） */
  background-color: rgba(255, 255, 255, 0.02);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 16px;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5);
}

/* =========================================
   Premium Dark Cockpit v0.5.1：深空底盤與高對比迷宮
========================================= */
.cell {
  position: absolute;
  transform-style: preserve-3d;
}

.cell.path {
  overflow: hidden;
  border-radius: 2px;
  background: var(--coreo-path);
  box-shadow:
    inset 0 0 0 1px rgba(245, 245, 247, 0.04),
    inset 0 0 0 1px var(--coreo-matrix-glow);
  transition: box-shadow 0.1s ease-out;
}

/* v0.9.1 Stage01：低反光的冷黑金屬路面，只承接牆緣的藍光，不把整條路徑染亮。 */
.stage-01 .cell.path {
  background:
    linear-gradient(145deg, rgba(48, 64, 85, 0.34), transparent 42%),
    var(--coreo-s1-path);
  box-shadow:
    inset 0 0 0 1px rgba(221, 247, 255, 0.055),
    inset 0 0 8px rgba(0, 140, 255, 0.045);
}

.stage-02 .cell.path {
  background:
    linear-gradient(145deg, rgba(42, 58, 82, 0.4), transparent 44%),
    var(--coreo-s2-path);
  box-shadow:
    inset 0 0 0 1px rgba(229, 243, 255, 0.06),
    inset 0 0 8px rgba(47, 99, 255, 0.055);
}

.cell.path::before,
.cell.path::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.cell.path::before {
  display: none;
}

/* v0.6.9：矩陣線條回歸——這個偽元素原本是閒置佔位（background:none），
   借用它畫路徑接縫的白金脈衝線，靜態 box-shadow 值不隨觸發改變，只切 opacity（合成層屬性，
   不會像 v0.5.27 之前的全格 box-shadow 重算那樣拖垮 iPhone/Android） */
.cell.path::after {
  border-radius: 2px;
  box-shadow:
    inset 0 0 0 1px var(--coreo-matrix-glow-platinum),
    inset 0 0 10px var(--coreo-matrix-glow-platinum-soft);
  opacity: 0;
  transition: opacity 1.1s ease-in;
}

/* v0.5.24：動能軌跡 Trail——主角走過的格子留下極低調的淡冰藍餘光，快速消退，
   不是獨立格子系統（路徑格已貪婪合併成大區塊），改用跟隨玩家座標生成的小型殘光點，
   刻意做得小、暗、快消退，避免被誤認為可收集物或干擾 Core Shard 視覺 */
.motion-trail {
  position: absolute;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--coreo-trail);
  box-shadow: 0 0 7px rgba(212, 240, 255, 0.4);
  opacity: 0.3;
  pointer-events: none;
  transform: translate(-50%, -50%) translateZ(3px);
  animation: trail-fade 0.55s ease-out forwards;
}
@keyframes trail-fade {
  0% { opacity: 0.3; transform: translate(-50%, -50%) translateZ(3px) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) translateZ(3px) scale(0.35); }
}

.cell.wall {
  /* v0.5.18：GEM 冷鋼藍灰方向，牆體加入微弱藍紫色相，打破純中性灰的死板感 */
  /* v0.5.24：GPT 裁決第一優先——牆體邊緣高光加強，讓牆體從深空背景與路徑中更清楚浮出來 */
  background: linear-gradient(145deg, #18202C 0%, var(--coreo-s1-wall-top) 62%, #101722 100%);
  border-radius: 14px;
  transform: translateZ(18px);
  transition: box-shadow 1.5s ease-in;
  box-shadow:
    0 0 0 1px var(--coreo-matrix-glow),
    0 0 16px rgba(0, 229, 255, 0.075),
    0 18px 34px rgba(4, 4, 6, 0.62),
    inset 0 1px 0 rgba(245, 245, 247, 0.28),
    inset 0 0 10px rgba(212, 240, 255, 0.10),
    inset 0 0 0 1px var(--coreo-edge-highlight);
}

/* v0.9.1 Stage01：維持迷宮幾何，不仿造參考圖的膠囊外形；僅轉譯其材質層級。
   外圈是冷白硬質護邊，內側依序為黑色接縫、電光藍能量槽、冰青細高光與黑色主體。 */
.stage-01 .cell.wall {
  border: 2px solid transparent;
  border-radius: 8px;
  background:
    linear-gradient(145deg, #111924 0%, var(--coreo-s1-wall-top) 42%, #070B11 76%, #131D29 100%) padding-box,
    linear-gradient(145deg,
      var(--coreo-s1-shell-hot) 0%,
      #B9C8D9 26%,
      #62758B 58%,
      var(--coreo-s1-shell) 82%,
      #899CAF 100%) border-box;
  box-shadow:
    0 9px 20px rgba(0, 4, 10, 0.3),
    0 2px 7px rgba(0, 140, 255, 0.12),
    inset 0 0 0 1px #010308,
    inset 0 0 0 3px rgba(0, 140, 255, 0.95),
    inset 0 0 0 4px rgba(66, 200, 255, 0.72),
    inset 0 0 0 5px rgba(221, 247, 255, 0.52),
    inset 0 0 12px rgba(0, 140, 255, 0.13);
}

.stage-01 .cell.wall::before {
  inset: 5px;
  border-radius: 3px;
}

/* v0.6.9：這個偽元素原本也是閒置佔位（opacity 永遠 0，之前沒有任何觸發點），
   借用它畫牆體接縫的白金脈衝，同樣只切 opacity，background 漸層值是靜態的 */
.cell.wall::before {
  content: '';
  position: absolute;
  inset: 1px;
  border-radius: 13px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.2s ease-in;
  background:
    linear-gradient(90deg, transparent 0%, var(--coreo-matrix-glow-platinum-soft) 50%, transparent 100%),
    linear-gradient(180deg, var(--coreo-matrix-glow-platinum), transparent 44%);
}

/* v0.6.9：Core Pulse 觸發瞬間，只切換 #world 這一個 class，實際發光靠上面兩個偽元素的
   opacity transition 完成——快速亮起（0.12s）覆蓋掉 base rule 的慢速冷卻 transition，
   跟 v0.5.19 「#world.energized 快進慢出」是同一個技巧，但改切 opacity 不改切 box-shadow，
   不會重踩 v0.5.27 修過的全地圖重繪效能坑。與 Supernova Burst 疊加觸發，不取代它。 */
#world.matrix-pulse .cell.path::after,
#world.matrix-pulse .cell.wall::before {
  opacity: 1;
  transition: opacity 0.12s ease-out;
}

/* v0.9.2 Stage02：沿用 Stage01 的精密分層材質，但以深鈷冰藍建立更冷、更緊張的關卡身分。
   幾何與 0.92 視覺留縫維持原設計；不使用紫色，也不靠加深黑度區分關卡。 */
.stage-02 .cell.wall {
  border: 2px solid transparent;
  border-radius: 8px;
  background:
    linear-gradient(145deg, #101A2A 0%, var(--coreo-s2-wall-top) 43%, #070C18 76%, #14223A 100%) padding-box,
    linear-gradient(145deg,
      var(--coreo-s2-shell-hot) 0%,
      #AABCD2 27%,
      #536B88 58%,
      var(--coreo-s2-shell) 82%,
      #748BA5 100%) border-box;
  transform: translateZ(18px) scale(0.92);
  transform-origin: center;
  box-shadow:
    0 9px 20px rgba(0, 4, 12, 0.32),
    0 2px 7px rgba(47, 99, 255, 0.14),
    inset 0 0 0 1px #01030A,
    inset 0 0 0 3px rgba(47, 99, 255, 0.96),
    inset 0 0 0 4px rgba(115, 183, 255, 0.72),
    inset 0 0 0 5px rgba(229, 243, 255, 0.48),
    inset 0 0 12px rgba(47, 99, 255, 0.14);
}

.stage-02 .cell.wall::before {
  inset: 5px;
  border-radius: 3px;
}

/* v0.10.6.1：兩關都解除 paint containment。Stage01 上方入口移到地圖第一列後，
   Android 會嚴格裁掉超出 #world 邊界的牆緣高光；保留 layout/style containment 與
   camera-rig 的視窗裁切，只放行牆體自身的邊線與微光，不改地圖尺寸或鏡頭位置。 */
#world.stage-01,
#world.stage-02 {
  contain: layout style;
  overflow: visible;
}

/* Stage 03 Android：獨立解除世界上緣 paint 裁切，不改 Stage 01/02 規則。 */
#world.stage-03 {
  contain: layout style;
  overflow: visible;
}

/* 核心凹槽區（代號7）牆體：白金邊緣微光，只做內側反射不整面發光。
   v0.6：座標判定修正後這組樣式終於會真的套用到牆上，順勢把強度調到肉眼可辨（原本太弱形同沒有） */
/* v0.8.3：Sean/GPT 最高優先覆蓋裁決——Stage02 禁止黃色，凹槽內側反射不再是例外，
   this class 只會套用在 Stage02 的牆（getWallZoneClass 對 Stage01 一律回傳 null），
   不需要額外的 .stage-02 前綴，直接改色即可，不影響 Stage01 */
.stage-02 .cell.wall.zone-vault {
  outline: 1px solid rgba(158, 220, 255, 0.34);
  outline-offset: -6px;
  filter: drop-shadow(0 0 5px rgba(47, 99, 255, 0.18));
}

/* EMBER 守護區牆體：熔岩暗湧底光，緩慢呼吸，克制不做滿地橘紅 */
.cell.wall.zone-guard {
  animation: guard-breathing 4s infinite alternate ease-in-out;
}
@keyframes guard-breathing {
  0% { box-shadow: inset 0 -6px 14px rgba(255, 69, 58, 0.05); }
  100% { box-shadow: inset 0 -6px 22px rgba(255, 69, 58, 0.32); }
}

/* 誘敵通道牆體：冷藍引導線，維持克制但要看得出來是一條線索 */
.stage-02 .cell.wall.zone-lure {
  outline: 1px solid rgba(115, 183, 255, 0.28);
  outline-offset: -6px;
}

/* v0.6.7：GPT 正式裁決——Core Pulse 大光源改為 Supernova Burst（超新星冷爆發）。
   不再用黃色地板/全地圖 overlay，改成以拾取點為中心的局部爆發：
   鈦白 #FFFFFF 主爆發（0.1s 瞬間點亮）→ 快速收斂（0.4s）→ 極短極光青/深鈷藍餘暉（0.1-0.2s）後完全消退。
   單一元素、生成後動畫播完自動移除，效能成本固定，不觸碰任何既有 .cell 元素。
   黃金感保留給出口 Core Ring 與 Core Pulse 道具本身（.light-core-item.upgraded），
   大光源「拾取瞬間」不再用黃色。 */
.supernova-burst-fx {
  position: absolute;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  pointer-events: none;
  z-index: 85;
  transform: translate(-50%, -50%) translateZ(9px) scale(0.35);
  opacity: 0;
  background: radial-gradient(circle,
    rgba(244, 248, 255, 0.7) 0%,
    rgba(124, 92, 255, 0.32) 34%,
    rgba(0, 240, 255, 0.14) 58%,
    transparent 78%);
  animation: supernova-burst-anim 0.65s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

.stage-01 .supernova-burst-fx {
  background: radial-gradient(circle,
    rgba(255, 255, 255, 0.82) 0%,
    rgba(221, 247, 255, 0.58) 20%,
    rgba(0, 140, 255, 0.28) 42%,
    rgba(0, 207, 255, 0.1) 60%,
    transparent 76%);
}

.stage-02 .supernova-burst-fx {
  background: radial-gradient(circle,
    rgba(255, 255, 255, 0.84) 0%,
    rgba(114, 242, 229, 0.62) 20%,
    rgba(0, 214, 199, 0.3) 42%,
    rgba(47, 99, 255, 0.1) 61%,
    transparent 76%);
}
@keyframes supernova-burst-anim {
  0% { opacity: 0; transform: translate(-50%, -50%) translateZ(9px) scale(0.35); }
  15% { opacity: 1; transform: translate(-50%, -50%) translateZ(9px) scale(1); }
  60% { opacity: 0.45; transform: translate(-50%, -50%) translateZ(9px) scale(1.1); }
  100% { opacity: 0; transform: translate(-50%, -50%) translateZ(9px) scale(1.22); }
}

.cell.wall::after {
  content: '';
  position: absolute;
  bottom: -18px;
  left: 0;
  width: 100%;
  height: 18px;
  background:
    linear-gradient(180deg, rgba(141, 169, 196, 0.18), transparent 24%),
    linear-gradient(180deg, var(--coreo-s1-wall-side), var(--coreo-s1-wall-shadow));
  box-shadow: inset 0 1px 0 rgba(212, 240, 255, 0.18);
  transform-origin: top;
  transform: rotateX(-90deg);
  border-radius: 0 0 14px 14px;
}

/* Stage01 的高度由清楚的冷黑藍側壁表現；柔影只負責接地，不再用純黑尖楔冒充厚度。 */
.stage-01 .cell.wall::after {
  bottom: -18px;
  left: 2px;
  width: calc(100% - 4px);
  height: 18px;
  background:
    linear-gradient(180deg, rgba(221, 247, 255, 0.2) 0 1px, transparent 2px),
    linear-gradient(180deg, #202D3D 0%, var(--coreo-s1-wall-side) 48%, #101722 100%);
  box-shadow:
    inset 0 1px 0 rgba(66, 200, 255, 0.22),
    0 7px 13px var(--coreo-s1-wall-shadow),
    0 2px 8px rgba(0, 140, 255, 0.08);
  border-radius: 0 0 5px 5px;
}

.stage-02 .cell.wall::after {
  bottom: -18px;
  left: 2px;
  width: calc(100% - 4px);
  height: 18px;
  background:
    linear-gradient(180deg, rgba(229, 243, 255, 0.18) 0 1px, transparent 2px),
    linear-gradient(180deg, #223653 0%, var(--coreo-s2-wall-side) 48%, #0D1727 100%);
  box-shadow:
    inset 0 1px 0 rgba(115, 183, 255, 0.22),
    0 7px 13px var(--coreo-s2-wall-shadow),
    0 2px 8px rgba(47, 99, 255, 0.09);
  border-radius: 0 0 5px 5px;
}

.cell.entity {
  pointer-events: none;
  transform: translateZ(1px);
}

.cell.start {
  background: radial-gradient(circle at 50% 50%, rgba(245, 245, 247, 0.13) 0 24%, transparent 25%);
}

.cell.start::before,
.cell.start::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  pointer-events: none;
}

/* Stage02 正式入口門檻：中央缺口提供真實入口，起點只做精密定位，不靠霧光撐場。 */
.stage-02 .cell.start {
  border: 1px solid rgba(115, 183, 255, 0.46);
  border-top-color: rgba(229, 243, 255, 0.72);
  border-radius: 6px;
  background:
    linear-gradient(180deg, rgba(229, 243, 255, 0.08), transparent 28%),
    linear-gradient(145deg, #17253A 0%, #0A101D 62%, #101D31 100%);
  box-shadow:
    inset 0 0 0 2px rgba(1, 3, 10, 0.88),
    inset 0 0 0 3px rgba(47, 99, 255, 0.32),
    0 2px 8px rgba(47, 99, 255, 0.12);
}

.stage-02 .cell.start::before {
  width: 28px;
  height: 28px;
  border-color: var(--coreo-s2-guide-secondary);
  border-top-color: var(--coreo-s2-highlight);
  box-shadow: 0 0 5px rgba(229, 243, 255, 0.34), inset 0 0 8px rgba(47, 99, 255, 0.24);
}

.stage-02 .cell.start::after {
  width: 9px;
  height: 9px;
  background: var(--coreo-s2-highlight);
  box-shadow: 0 0 7px rgba(115, 183, 255, 0.62);
}

.cell.start::before {
  width: 30px;
  height: 30px;
  border: 2px solid rgba(134, 134, 139, 0.54);
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0.82);
  box-shadow: inset 0 0 10px rgba(245, 245, 247, 0.10);
}

.cell.start::after {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: rgba(245, 245, 247, 0.62);
  transform: translate(-50%, -50%);
  box-shadow: 0 0 10px rgba(245, 245, 247, 0.24);
}

/* Stage 03：紫水晶能源閘門。入口覆層只負責視覺，碰撞仍由原迷宮格控制。 */
.stage03-entrance-gate {
  position: absolute;
  pointer-events: none;
  z-index: 8;
  transform: translateZ(25px);
  box-sizing: border-box;
  border: 2px solid var(--coreo-s3-shell);
  border-bottom: 0;
  border-radius: 12px 12px 0 0;
  background:
    linear-gradient(180deg, rgba(4, 2, 10, .98) 0%, rgba(12, 7, 24, .92) 48%, rgba(24, 15, 44, .28) 84%, transparent 100%);
  box-shadow:
    0 0 0 1px rgba(242, 235, 255, .58),
    0 0 16px rgba(141, 99, 210, .72),
    inset 0 0 20px rgba(141, 99, 210, .22);
}
.stage03-entrance-gate::before,
.stage03-entrance-gate::after {
  content: '';
  position: absolute;
  pointer-events: none;
}
.stage03-entrance-gate::before {
  left: 7px;
  right: 7px;
  top: 8px;
  bottom: 0;
  border: 2px solid var(--coreo-s3-shell-hot);
  border-bottom: 0;
  border-radius: 8px 8px 0 0;
  box-shadow: 0 0 10px rgba(183, 155, 234, .72);
}
.stage03-entrance-gate::after {
  left: 5px;
  right: 5px;
  bottom: -2px;
  height: 4px;
  border-radius: 4px;
  background: linear-gradient(90deg, transparent, var(--coreo-s3-shell-hot) 18% 82%, transparent);
  box-shadow: 0 0 12px rgba(141, 99, 210, .88);
}
.stage-03 .cell.start {
  border-radius: 7px;
  background: linear-gradient(180deg, rgba(141, 99, 210, .16), rgba(38, 34, 49, .72));
  box-shadow: inset 0 0 0 1px rgba(242, 235, 255, .28), inset 0 0 16px rgba(141, 99, 210, .2);
}
.stage-03 .cell.start::before {
  border-color: var(--coreo-s3-shell);
  border-top-color: var(--coreo-s3-shell-hot);
  box-shadow: 0 0 9px rgba(183, 155, 234, .66), inset 0 0 8px rgba(141, 99, 210, .34);
}
.stage-03 .cell.start::after {
  background: var(--coreo-s3-shell-hot);
  box-shadow: 0 0 9px rgba(183, 155, 234, .82);
}

/* v0.5.15：出口改為「白金光環 Core Ring」+ 底部光柱，取代原本綠色虛線框 */
/* v0.5.24：GPT 裁決第四優先，白金光環改用 Core Pulse 白金色系，加一層淡冰藍內光跟 Core Pulse 建立視覺關聯 */
.cell.exit {
  box-shadow:
    inset 0 0 30px rgba(0, 230, 255, 0.24),
    inset 0 0 46px rgba(100, 210, 255, 0.12);
}

/* v0.6：Stage02 出口漸進視覺——拿到部分但未達門檻的 Pulse 時，疊加暗化＋收斂邊框，
   跟拿滿門檻後的完整白金光環做出明顯差異 */
.cell.exit.partial-charged {
  filter: brightness(0.8);
  box-shadow: inset 0 0 15px rgba(124, 92, 255, 0.18);
  border: 1px solid rgba(124, 92, 255, 0.35);
}

.cell.exit::before,
.cell.exit::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  pointer-events: none;
}

/* 緩慢旋轉的白金光環 */
.cell.exit::before {
  width: 38px;
  height: 38px;
  border: 2px solid var(--coreo-stage-secured);
  border-top-color: transparent;
  border-radius: 50%;
  transform: translate(-50%, -50%) rotate(0deg);
  box-shadow: 0 0 20px rgba(0, 230, 255, 0.55);
  animation: exit-ring-spin 3.4s linear infinite;
}

/* 底部往上打的光柱：白金起頭、淡冰藍收尾，跟 Core Pulse 建立色彩關聯 */
.cell.exit::after {
  width: 5px;
  height: 120px;
  bottom: 50%;
  top: auto;
  background: linear-gradient(to top, rgba(124, 92, 255, 0.55), rgba(100, 210, 255, 0.28) 65%, transparent);
  transform: translate(-50%, 0);
}

/* v0.8.2：GPT 明確裁決 Stage02 不得是黃光關，出口光環是「永久旋轉、不是瞬間效果」，
   之前每一輪任務包範圍都太窄沒人碰過這裡，才會一直看到白金色。Stage01 出口維持不動，
   Stage02 出口改用線性通電光效同一套冷白/冰青色系，兩關视觉語言各自獨立不互相影響。 */
.stage-02 .cell.exit {
  background: radial-gradient(circle at 50% 50%, rgba(229, 243, 255, 0.11) 0 18%, rgba(47, 99, 255, 0.12) 19% 46%, transparent 66%);
  box-shadow:
    inset 0 0 26px rgba(47, 99, 255, 0.24),
    inset 0 0 42px rgba(115, 183, 255, 0.12);
}
.stage-02 .cell.exit.partial-charged {
  box-shadow: inset 0 0 15px rgba(47, 99, 255, 0.18);
  border: 1px solid rgba(115, 183, 255, 0.34);
}
.stage-02 .cell.exit::before {
  border: 2px solid var(--coreo-s2-highlight);
  border-top-color: transparent;
  box-shadow: 0 0 5px rgba(229, 243, 255, 0.5), 0 0 15px rgba(47, 99, 255, 0.52);
}
.stage-02 .cell.exit::after {
  width: 4px;
  background: linear-gradient(to top, rgba(229, 243, 255, 0.78), rgba(115, 183, 255, 0.4) 42%, rgba(47, 99, 255, 0.14) 74%, transparent);
}

/* Stage 03 出口跟隨紫水晶關卡身分，避免殘留前兩關的冰青色。 */
.stage-03 .cell.exit {
  background: radial-gradient(circle at 50% 50%, rgba(242, 235, 255, .13) 0 18%, rgba(141, 99, 210, .16) 19% 48%, transparent 68%);
  box-shadow: inset 0 0 28px rgba(141, 99, 210, .3), inset 0 0 44px rgba(183, 155, 234, .14);
}
.stage-03 .cell.exit.partial-charged {
  filter: brightness(.86);
  border: 1px solid rgba(183, 155, 234, .46);
  box-shadow: inset 0 0 17px rgba(122, 75, 208, .3);
}
.stage-03 .cell.exit::before {
  border-color: var(--coreo-s3-shell-hot);
  border-top-color: transparent;
  box-shadow: 0 0 7px rgba(242, 235, 255, .62), 0 0 18px rgba(141, 99, 210, .7);
}
.stage-03 .cell.exit::after {
  width: 4px;
  background: linear-gradient(to top, rgba(242, 235, 255, .86), rgba(183, 155, 234, .5) 42%, rgba(141, 99, 210, .2) 74%, transparent);
}

@keyframes exit-ring-spin {
  0% { transform: translate(-50%, -50%) rotate(0deg); }
  100% { transform: translate(-50%, -50%) rotate(360deg); }
}
/* =========================================
   動態物件 (Player & Light Core)
========================================= */
/* 外層定位容器：只負責座標與固定 Z 高度，絕對不套用動畫 */
.actor {
  position: absolute;
  transform-style: preserve-3d;
  /* Z 軸數值固定為 12px 貼地感，JS 絕對不可再覆寫此屬性 */
  transform: translate(-50%, -50%) translateZ(10px);
  transition: top 0.07s linear, left 0.07s linear;
  z-index: 100;
}

/* v0.10.5.1：正式座標已由 requestAnimationFrame 逐幀更新；不要再用 CSS transition
   追趕上一幀的位置，避免 iOS 在中央縱向路線與相機同步移動時產生細抖。 */
#player.actor {
  z-index: 120;
  transition: none;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
#enemy.actor { z-index: 100; pointer-events: none; }

#player.actor.victory-actor {
  z-index: 5000;
  transition: none;
}

#player.actor.victory-source-hidden {
  opacity: 0;
}

.victory-player-clone {
  position: fixed;
  width: 62px;
  height: 62px;
  left: 50%;
  top: 50%;
  z-index: 6500;
  pointer-events: none;
  border-radius: 50%;
  background-image: url('../assets/player.png');
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  filter: drop-shadow(0 0 14px rgba(0, 229, 255, 0.8)) drop-shadow(0 0 30px rgba(0, 229, 255, 0.5));
  transform: translate(-50%, -50%) scale(1);
  transform-origin: center center;
}

/* 內層視覺容器：負責圖片、發光、所有動畫縮放與旋轉 */
.actor-sprite {
  position: relative;
  width: 62px;
  height: 62px;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  border-radius: 50%;
  transform-style: preserve-3d;
  transition: transform 0.1s ease, filter 0.3s ease;
}

/* 主角內層視覺 */
#player .actor-sprite {
  background-image: url('../assets/player.png');
  filter: drop-shadow(0 0 14px rgba(0, 229, 255, 0.8)) drop-shadow(0 0 30px rgba(0, 229, 255, 0.5));
  /* 光源拾取會同時動畫 transform 與 filter；固定成獨立合成層，避免重繪回傳到定位外層。 */
  will-change: transform, filter;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

/* 反派內層視覺：EMBER｜熾核獵者專屬圖 */
/* v0.5.24：GPT/GEM 裁決，主色從霓虹紅粉 #FF2D55 改為熔岩橘紅 #FF5722，光暈加強、壓迫感更明確 */
#enemy .actor-sprite {
  background-image: url('../assets/enemy_ember.png');
  filter: drop-shadow(0 0 18px rgba(255, 69, 58, 0.95)) drop-shadow(0 0 42px rgba(255, 69, 58, 0.65));
}

/* --- 能量分級系統 (LIGHT CORE) --- */
.light-core-item {
  position: absolute;
  top: 50%;
  left: 50%;
  transform-style: preserve-3d;
}

/* 等級 4: 一般能量 (冰藍小圓點) */
.light-core-item.standard,
.light-core-item.basic {
  width: 14px;
  height: 14px;
  background: var(--coreo-core-basic);
  border-radius: 50%;
  box-shadow: 0 0 11px var(--coreo-core-basic-glow), 0 0 22px rgba(0, 229, 255, 0.20);
  animation: float-core-std 2s ease-in-out infinite;
}

.stage-02 .light-core-item.standard,
.stage-02 .light-core-item.basic {
  background: var(--coreo-s2-core-basic);
  box-shadow: 0 0 11px var(--coreo-s2-guide-secondary), 0 0 22px rgba(100, 210, 255, 0.2);
}

/* 等級 5: 強化能量 (v0.5.24 白金菱形，取代原本偏黃廉價感，死路支線獎勵) */
 .light-core-item.upgraded,
.light-core-item.boost {
  width: 24px;
  height: 24px;
  background: linear-gradient(145deg, var(--coreo-core-boost) 0%, var(--coreo-core-boost-deep) 100%);
  border-radius: 6px;
  transform: translate(-50%, -50%) translateZ(18px) rotate(45deg);
  box-shadow: 0 0 15px rgba(124, 92, 255, 0.82), 0 0 30px rgba(100, 210, 255, 0.2);
  animation: float-core-upg 2s ease-in-out infinite;
}

/* Stage01 大光源：保留原菱形，改為高密度皇家電藍／冰青／冷白核心，避免藍紫軟糖感。 */
.stage-01 .light-core-item.upgraded,
.stage-01 .light-core-item.boost {
  background:
    radial-gradient(circle at 34% 28%, #FFFFFF 0 9%, #DDF7FF 10% 20%, transparent 21%),
    linear-gradient(145deg, #00CFFF 0%, #0878FF 42%, #004FD6 76%, #001D58 100%);
  border: 1px solid rgba(221, 247, 255, 0.92);
  border-radius: 4px;
  box-shadow:
    0 0 0 2px rgba(0, 17, 43, 0.92),
    0 0 0 3px rgba(66, 200, 255, 0.72),
    0 0 12px rgba(0, 140, 255, 0.75),
    0 0 22px rgba(0, 207, 255, 0.24),
    inset 0 0 7px rgba(221, 247, 255, 0.48);
}

/* v0.8.3：Sean/GPT 最高優先覆蓋裁決——Stage02 的 Core Pulse 道具本體也不能是白金黃，
   Stage01 維持原本白金外觀不動 */
.stage-02 .light-core-item.upgraded,
.stage-02 .light-core-item.boost {
  background:
    radial-gradient(circle at 34% 28%, #FFFFFF 0 9%, #E8FFFC 10% 20%, transparent 21%),
    linear-gradient(145deg, #72F2E5 0%, var(--coreo-s2-core-boost) 40%, #008F91 76%, #003D4B 100%);
  border: 1px solid rgba(232, 255, 252, 0.94);
  border-radius: 4px;
  box-shadow:
    0 0 0 2px rgba(0, 27, 38, 0.94),
    0 0 0 3px rgba(114, 242, 229, 0.7),
    0 0 12px rgba(0, 214, 199, 0.78),
    0 0 22px rgba(47, 99, 255, 0.2),
    inset 0 0 7px rgba(232, 255, 252, 0.5);
}

@keyframes float-core-std {
  0%, 100% { transform: translate(-50%, -50%) translateZ(10px); }
  50% { transform: translate(-50%, -50%) translateZ(10px); }
}
@keyframes float-core-upg {
  0%, 100% { transform: translate(-50%, -50%) translateZ(14px) rotate(45deg); }
  50% { transform: translate(-50%, -50%) translateZ(26px) rotate(45deg); }
}

/* 收集能量時的放大動畫（作用在內層 .actor-sprite，不碰外層定位） */
 .actor-sprite.player-collect-anim-4,
.actor-sprite.player-collect-basic {
  animation: player-joy-4 0.75s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
@keyframes player-joy-4 {
  0%, 100% { transform: scale(1) rotate(0deg); }
  25% { transform: scale(1.35) rotate(-10deg); }
  50% { transform: scale(1.35) rotate(10deg); }
  75% { transform: scale(1.18) rotate(-5deg); }
}

 .actor-sprite.player-collect-anim-5,
.actor-sprite.player-collect-boost {
  animation: player-joy-5 1s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
@keyframes player-joy-5 {
  0%, 100% { transform: scale(1) rotate(0deg); }
  20% { transform: scale(1.65) rotate(-15deg); }
  40% { transform: scale(1.65) rotate(15deg); }
  60% { transform: scale(1.38) rotate(-10deg); }
  80% { transform: scale(1.2) rotate(5deg); }
}

/* =========================================
   v0.10.2 Full-screen Continuous Swipe Control
========================================= */
#joystick-zone {
  position: fixed;
  inset: 0;
  z-index: 2000;
  pointer-events: auto;
  touch-action: none;
  overscroll-behavior: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.actor-sprite.shake {
  animation: wall-bump 0.2s cubic-bezier(.36,.07,.19,.97) both;
}

@keyframes wall-bump {
  0%, 100% { transform: rotate(0deg) scale(1); }
  25% { transform: rotate(8deg) scale(0.95); }
  75% { transform: rotate(-8deg) scale(0.95); }
}

/* v0.5.17：過關 Cinematic Zoom——持續往上飄升脫離迷宮結構、進入畫面上方空白深空區，到頂點才凍結暗場 */
.actor-sprite.player-victory-zoom {
  animation: victory-zoom 2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.victory-player-clone.player-victory-zoom {
  animation: victory-clone-zoom-up 2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes victory-zoom {
  0% { transform: scale(1) translateY(0); filter: drop-shadow(0 0 14px rgba(0, 229, 255, 0.8)); opacity: 1; }
  45% { transform: scale(2.4) translateY(-150px); filter: drop-shadow(0 0 32px rgba(0, 229, 255, 0.95)); opacity: 1; }
  85% { opacity: 1; }
  100% { transform: scale(3.8) translateY(-340px); filter: drop-shadow(0 0 46px rgba(0, 229, 255, 1)); opacity: 0; }
}
/* v0.7.1：分身動畫原本只有 transform 變化，opacity 全程停在預設值 1，animation 又是 forwards
   fill-mode，播完會停在最後一幀不會消失，導致跟 2050ms 後才出現的 STAGE SECURED 疊層同框——
   Sean 截圖回報過關放大角色卡在文字正上方破壞美感。修法：最後一段淡出到 0，讓分身在放大到頂點
   附近時自然消失，STAGE SECURED 才單獨浮現，不再兩者疊在一起。 */
@keyframes victory-clone-zoom-up {
  0% { transform: translate(-50%, -50%) scale(1); filter: drop-shadow(0 0 14px rgba(0, 229, 255, 0.8)); opacity: 1; }
  45% { transform: translate(-50%, calc(-50% - 16vh)) scale(2.4); filter: drop-shadow(0 0 32px rgba(0, 229, 255, 0.95)); opacity: 1; }
  85% { opacity: 1; }
  100% { transform: translate(-50%, calc(-50% - 28vh)) scale(3.8); filter: drop-shadow(0 0 46px rgba(0, 229, 255, 1)); opacity: 0; }
}

/* v0.6：出口方向不再固定在地圖上方（Stage02 刻意反過來，讓玩家摸不準出口方位），
   放大脫離的方向要跟著出口實際方向走，往下的鏡射版本 */
.actor-sprite.player-victory-zoom-down {
  animation: victory-zoom-down 2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.victory-player-clone.player-victory-zoom-down {
  animation: victory-clone-zoom-down 2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes victory-zoom-down {
  0% { transform: scale(1) translateY(0); filter: drop-shadow(0 0 14px rgba(0, 229, 255, 0.8)); opacity: 1; }
  45% { transform: scale(2.4) translateY(150px); filter: drop-shadow(0 0 32px rgba(0, 229, 255, 0.95)); opacity: 1; }
  85% { opacity: 1; }
  100% { transform: scale(3.8) translateY(340px); filter: drop-shadow(0 0 46px rgba(0, 229, 255, 1)); opacity: 0; }
}
/* v0.7.1：跟 victory-clone-zoom-up 同一個修法，最後淡出到 0，見上方註解 */
@keyframes victory-clone-zoom-down {
  0% { transform: translate(-50%, -50%) scale(1); filter: drop-shadow(0 0 14px rgba(0, 229, 255, 0.8)); opacity: 1; }
  45% { transform: translate(-50%, calc(-50% + 14vh)) scale(2.4); filter: drop-shadow(0 0 32px rgba(0, 229, 255, 0.95)); opacity: 1; }
  85% { opacity: 1; }
  100% { transform: translate(-50%, calc(-50% + 24vh)) scale(3.8); filter: drop-shadow(0 0 46px rgba(0, 229, 255, 1)); opacity: 0; }
}

.victory-burst {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 3px solid var(--coreo-glow-core);
  box-shadow: 0 0 30px rgba(0, 229, 255, 0.8);
  transform: translate(-50%, -50%) scale(0.5);
  opacity: 1;
  pointer-events: none;
  z-index: 200;
  animation: victory-burst-expand 2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes victory-burst-expand {
  0% { transform: translate(-50%, -50%) scale(0.5); opacity: 0.9; }
  100% { transform: translate(-50%, -50%) scale(16); opacity: 0; }
}

#level-complete-overlay {
  position: fixed;
  inset: 0;
  background-color: rgba(21, 21, 23, 0.88);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 3000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease;
}

#level-complete-overlay.show { opacity: 1; pointer-events: auto; }

.lc-title {
  font-size: 24px;
  font-weight: 750;
  color: var(--coreo-success);
  letter-spacing: 4px;
}

.lc-line {
  width: 48px;
  height: 2px;
  background: linear-gradient(90deg, var(--coreo-s1-guide), var(--coreo-s1-highlight));
  margin: 12px 0;
  box-shadow: 0 0 14px rgba(48, 209, 88, 0.60);
}

/* v0.8.3：Stage02 版 STAGE SECURED 底線改冷白/冰青漸層，不用帶黃的 --coreo-credit */
#level-complete-overlay.stage-02 .lc-line {
  background: linear-gradient(90deg, var(--coreo-glow-core), #F4F8FF);
}

/* ==============================================
   Gameplay Layer (Type 6, Enemy States, Effects)
   v0.5.24：顏色改用 --coreo-enemy-red 熔岩橘紅 (#FF5722 = rgb(255,87,34))
============================================== */

/* 躲藏凹槽 Type 6 (暗化、稍微縮小產生凹陷感) */
.cell.entity.pocket {
  background: rgba(0, 0, 0, 0.28);
  border-radius: 8px;
  transform: translateZ(2px) scale(0.85);
  box-shadow: inset 0 2px 6px rgba(0,0,0,0.35);
}

/* 反派狀態：巡邏 (微弱橘紅光，全部作用在內層 .actor-sprite) */
.actor-sprite.enemy-state-patrol {
  filter: drop-shadow(0 0 10px rgba(255, 69, 58, 0.4)) drop-shadow(0 0 20px rgba(255, 69, 58, 0.2));
}

/* 反派狀態：警戒 (亮度提升) */
.actor-sprite.enemy-state-alert {
  filter: drop-shadow(0 0 17px rgba(255, 69, 58, 0.9)) drop-shadow(0 0 34px rgba(255, 69, 58, 0.6));
  animation: pulse-enemy-alert 0.5s infinite;
}
@keyframes pulse-enemy-alert {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}

/* 反派狀態：搜索（追丟玩家後，去最後出現位置附近找一下） */
.actor-sprite.enemy-state-search {
  filter: drop-shadow(0 0 13px rgba(255, 69, 58, 0.65)) drop-shadow(0 0 26px rgba(255, 69, 58, 0.35));
}

/* 反派狀態：追逐 (強烈殘影與抖動，v0.5.24 光暈加強壓迫感) */
.actor-sprite.enemy-state-chase {
  filter: drop-shadow(0 0 24px rgba(255, 69, 58, 1)) drop-shadow(0 0 46px rgba(255, 69, 58, 0.85));
}
.actor-sprite.enemy-state-chase::after {
  content: ''; position: absolute; inset: 0;
  background: inherit; border-radius: 50%; opacity: 0.5;
  animation: trail-shake 0.2s infinite alternate;
}
@keyframes trail-shake {
  0% { transform: translate(-2px, -2px) scale(1.1); }
  100% { transform: translate(2px, 2px) scale(1.1); }
}

/* 全域警戒紅光 Overlay */
#global-alert-overlay {
  position: fixed; inset: 0;
  background: radial-gradient(circle, transparent 40%, rgba(255, 69, 58, 0.12) 100%);
  pointer-events: none; opacity: 0; transition: opacity 0.3s; z-index: 400;
}
#global-alert-overlay.active { opacity: 1; }

/* 主角 Type 5 強化加速光尾（作用在內層 .actor-sprite） */
 .actor-sprite.player-speed-boost,
.actor-sprite.player-boosted {
  filter: drop-shadow(0 0 20px var(--coreo-credit-hot)) drop-shadow(0 0 30px var(--coreo-credit));
}
  .actor-sprite.player-speed-boost::before,
.actor-sprite.player-boosted::before {
  content: ''; position: absolute; top: 100%; left: 50%; width: 24px; height: 40px;
  background: linear-gradient(to bottom, var(--coreo-credit-hot), transparent);
  transform: translateX(-50%); opacity: 0.7; border-radius: 12px;
}

/* v0.5.27：Core Pulse 是出口啟動資源，不是加速道具，保留短暫亮起，避免長時間光尾影響幀率。
   v0.6.7：GPT 裁決 Core Pulse 不再用黃色，peak 瞬間改成鈦白高壓閃光，呼應 Supernova Burst */
.actor-sprite.player-pulse-feedback {
  animation: pulse-feedback 0.52s ease-out both;
}
@keyframes pulse-feedback {
  0% { transform: scale(1); filter: brightness(1) drop-shadow(0 0 14px rgba(0, 229, 255, 0.8)); }
  36% { transform: scale(1.18); filter: brightness(1.6) drop-shadow(0 0 22px rgba(255, 255, 255, 0.95)); }
  100% { transform: scale(1); filter: brightness(1) drop-shadow(0 0 14px rgba(0, 229, 255, 0.8)); }
}

/* ==============================================
   v0.5.1 CORE SIGNAL LOST 失敗演出特效
============================================== */

/* 疊層本體 */
#signal-lost-overlay {
  position: fixed; inset: 0; background-color: rgba(10, 10, 12, 0.9);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  z-index: 3000; opacity: 0; pointer-events: none; transition: opacity 0.2s ease;
}
#signal-lost-overlay.show { opacity: 1; pointer-events: auto; }

/* 畫面失焦與劇烈震動（作用於 camera-rig，避免與鏡頭捲動衝突） */
.world-shake-blur {
  animation: rig-shake 0.25s cubic-bezier(.36,.07,.19,.97) infinite;
  filter: blur(3px) brightness(0.8);
}
@keyframes rig-shake {
  0% { transform: translate(0, 0); }
  25% { transform: translate(6px, 4px); }
  50% { transform: translate(-6px, -4px); }
  75% { transform: translate(-4px, 6px); }
  100% { transform: translate(0, 0); }
}

/* 核心異常閃爍（作用於 player 內層 sprite，暗黑版用自己的冰藍/危險紅） */
 .actor-sprite.player-core-flash,
.actor-sprite.player-signal-lost {
  animation: core-flash 0.15s infinite alternate;
}
@keyframes core-flash {
  0% { filter: drop-shadow(0 0 14px rgba(0, 229, 255, 0.8)); }
  100% { filter: drop-shadow(0 0 25px var(--coreo-danger)) hue-rotate(140deg) brightness(2); }
}

/* 全域紅光閃現強化（v0.5.24 改熔岩橘紅 #FF5722） */
#global-alert-overlay.flash {
  background: radial-gradient(circle, transparent 20%, rgba(255, 69, 58, 0.45) 100%);
  opacity: 1;
  transition: opacity 0.05s;
}














/* v0.5 semantic actor aliases */
.actor-sprite.player-idle {
  filter: drop-shadow(0 0 14px rgba(0, 229, 255, 0.8)) drop-shadow(0 0 30px rgba(0, 229, 255, 0.5));
}
.actor-sprite.player-core-charged {
  filter: brightness(1.28) drop-shadow(0 0 18px var(--coreo-core-basic-glow));
}
.actor-sprite.villain-hunt {
  filter: brightness(1.18) drop-shadow(0 0 20px rgba(255, 69, 58, 1)) drop-shadow(0 0 44px rgba(255, 69, 58, 0.72));
}
.actor-sprite.villain-guard {
  filter: drop-shadow(0 0 14px var(--coreo-actor-villain-guard-glow)) drop-shadow(0 0 28px rgba(193, 18, 31, 0.35));
}
.actor-sprite.villain-interference {
  filter: drop-shadow(0 0 16px rgba(157, 0, 255, 0.75)) drop-shadow(0 0 32px rgba(157, 0, 255, 0.32));
}

/* =========================================
   STAGE BRIEFING (Cinematic Poster v1.1)
========================================= */
#stage-briefing {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100dvh;
  background-color: var(--coreo-bg-base);
  z-index: 9999;
  display: flex;
  flex-direction: column;
  color: var(--coreo-text-primary);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease;
  overflow: hidden;
}

#stage-briefing.show {
  opacity: 1;
  pointer-events: auto;
}

/* 背景與光暈：配合並排構圖置中放置 */
.briefing-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: linear-gradient(180deg, #090C12 0%, #05070C 48%, #03050A 100%);
}
.bg-glow-player {
  position: absolute;
  top: 50%;
  left: 18%;
  transform: translateY(-50%);
  width: min(38vw, 280px);
  height: min(38vw, 280px);
  background: radial-gradient(circle, rgba(0, 140, 255, 0.18) 0%, rgba(66, 200, 255, 0.07) 38%, transparent 70%);
  filter: blur(24px);
}
.bg-glow-ember {
  position: absolute;
  top: 50%;
  right: 18%;
  transform: translateY(-50%);
  width: min(42vw, 300px);
  height: min(42vw, 300px);
  background: radial-gradient(circle, rgba(255, 69, 58, 0.13) 0%, rgba(122, 16, 36, 0.05) 42%, transparent 70%);
  filter: blur(28px);
  transition: all 0.4s ease;
}

/* Stage 02 專屬背景光效強化 */
#stage-briefing.stage-02 .bg-glow-ember {
  background: radial-gradient(circle, rgba(255, 69, 58, 0.14) 0%, rgba(122, 16, 36, 0.055) 42%, transparent 70%);
  filter: blur(30px);
}

#stage-briefing.stage-02 .briefing-bg {
  background: linear-gradient(180deg, #080C14 0%, #040710 48%, #03050A 100%);
}

#stage-briefing.stage-02 .bg-glow-player {
  background: radial-gradient(circle, rgba(47, 99, 255, 0.18) 0%, rgba(115, 183, 255, 0.07) 38%, transparent 70%);
}

/* 內容容器 (保留 env 安全區與 overflow 防禦機制) */
.briefing-content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  height: 100%;
  justify-content: space-between;
  padding: env(safe-area-inset-top, 24px) 24px 20px;
  padding-bottom: max(env(safe-area-inset-bottom, 0px), 20px);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  min-height: 0;
}

/* 頂部極簡標題 */
.briefing-header {
  text-align: center;
  margin-top: 4vh;
}
.briefing-header h2 {
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: 3.5px;
  color: var(--coreo-s1-highlight);
  text-shadow: 0 0 12px rgba(0, 140, 255, 0.12);
  margin: 0 0 8px 0;
}
.briefing-header p {
  font-size: 0.75rem;
  font-weight: 300;
  color: #8DA9C4;
  opacity: 0.78;
  margin: 0;
  letter-spacing: 5px;
}

#stage-briefing.stage-02 .briefing-header h2 {
  color: var(--coreo-s2-highlight);
  text-shadow: 0 0 12px rgba(47, 99, 255, 0.16);
}

#stage-briefing.stage-02 .briefing-header p {
  color: var(--coreo-s2-tip);
  opacity: 0.68;
}

/* 中央並排對峙 */
.briefing-cinematic {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 12%;
}

.cinematic-player, .cinematic-ember {
  width: 42%;
  max-width: 170px;
  min-height: 0;
  position: relative;
}

.cinematic-player { animation: breathe-player 4s ease-in-out infinite; }
.cinematic-player img {
  width: 100%; height: auto;
  max-height: min(170px, 24vh);
  object-fit: contain;
  filter: drop-shadow(0 0 12px rgba(0, 140, 255, 0.48)) drop-shadow(0 0 22px rgba(66, 200, 255, 0.16));
}

.cinematic-ember { animation: breathe-ember 5s ease-in-out infinite; }
.cinematic-ember img {
  width: 100%; height: auto;
  max-height: min(170px, 24vh);
  object-fit: contain;
  filter: drop-shadow(0 0 14px rgba(255, 69, 58, 0.62)) drop-shadow(0 0 24px rgba(122, 16, 36, 0.2));
}

.cinematic-name {
  text-align: center;
  font-size: 10px;
  font-weight: 650;
  letter-spacing: 2px;
  margin-top: 12px;
}
.player-name { color: var(--coreo-s1-guide-secondary); }
.ember-name { color: var(--coreo-enemy-red); }

#stage-briefing.stage-02 .cinematic-player img {
  filter: drop-shadow(0 0 12px rgba(47, 99, 255, 0.5)) drop-shadow(0 0 22px rgba(115, 183, 255, 0.16));
}

#stage-briefing.stage-02 .player-name { color: var(--coreo-s2-guide-secondary); }

@keyframes breathe-player {
  0%, 100% { transform: translateY(0) scale(1); }
  50% { transform: translateY(-7px) scale(1.03); }
}
@keyframes breathe-ember {
  0%, 100% { transform: translateY(0) scale(1); }
  50% { transform: translateY(-6px) scale(1.025); }
}

/* 底部無框資訊區 */
.briefing-footer {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.briefing-info-container {
  padding: 0 12px;
}

.info-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 12px;
}
.info-row:nth-child(2) { margin-bottom: 16px; }

.info-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}
.shard-icon {
  background: var(--coreo-s1-core-basic);
  border-radius: 50%;
  box-shadow: 0 0 8px var(--coreo-s1-guide-secondary);
}
.pulse-icon {
  background: var(--coreo-s1-core-boost);
  transform: rotate(45deg);
  box-shadow: 0 0 8px rgba(0, 140, 255, 0.72);
}

/* v0.8.3：Stage02 版 Stage Briefing 的 Core Pulse icon 也不能是白金黃 */
#stage-briefing.stage-02 .pulse-icon {
  background: var(--coreo-s2-core-boost);
  box-shadow: 0 0 8px var(--coreo-s2-core-boost-soft);
}

#stage-briefing.stage-02 .shard-icon {
  background: var(--coreo-s2-core-basic);
  box-shadow: 0 0 8px var(--coreo-s2-guide-secondary);
}

.info-row p {
  font-size: 0.75rem;
  color: #A8BDD3;
  margin: 0;
  line-height: 1.4;
  letter-spacing: 0.5px;
}
.info-row p strong {
  color: var(--coreo-s1-highlight);
  font-weight: 600;
}

#stage-briefing.stage-02 .info-row p { color: #A7BBD2; }
#stage-briefing.stage-02 .info-row p strong { color: var(--coreo-s2-highlight); }

.info-mission {
  padding-top: 8px;
  text-align: center;
}
.info-mission p {
  font-size: 0.8rem;
  color: rgba(221, 247, 255, 0.9);
  margin: 0;
  font-weight: 400;
  letter-spacing: 0.8px;
  line-height: 1.5;
  transition: color 0.3s ease;
}

/* Stage02 任務是操作說明，不整段染成危險紅；EMBER 的橘紅語意由角色標籤本身承擔。 */
#stage-briefing.stage-02 .info-mission p {
  color: rgba(229, 243, 255, 0.9);
}

/* 高級座艙透明啟動鍵 */
#briefing-enter-btn {
  appearance: none;
  -webkit-appearance: none;
  background: linear-gradient(180deg, rgba(0, 140, 255, 0.035), transparent);
  border: 1px solid rgba(0, 140, 255, 0.56);
  color: var(--coreo-s1-highlight);
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 4px;
  padding: 18px;
  border-radius: 8px;
  width: 100%;
  text-align: center;
  cursor: pointer;
  transition: all 0.2s cubic-bezier(0.2, 0, 0, 1);
  margin: 0;
  box-shadow: inset 0 0 0 1px rgba(66, 200, 255, 0.045);
}

/* 點擊時邊緣發光爆發，不填滿底色 */
#briefing-enter-btn:active {
  box-shadow: 0 0 22px rgba(0, 140, 255, 0.56), inset 0 0 14px rgba(66, 200, 255, 0.18);
  transform: scale(0.98);
  border-color: rgba(66, 200, 255, 0.84);
  color: #fff;
}

/* v0.8.2：Stage 02 專屬按鈕配色改冷白/冰青，不用白金——GPT 明確裁決 Stage02 不是黃光關，
   舊版白金按鈕是 GEM 更早的 Stage Briefing 藍圖殘留，跟後來的色彩裁決衝突，這次一併修正 */
#stage-briefing.stage-02 #briefing-enter-btn {
  background: linear-gradient(180deg, rgba(47, 99, 255, 0.045), transparent);
  border-color: rgba(47, 99, 255, 0.62);
  color: var(--coreo-s2-highlight);
  box-shadow: inset 0 0 0 1px rgba(115, 183, 255, 0.05);
}
#stage-briefing.stage-02 #briefing-enter-btn:active {
  box-shadow: 0 0 22px rgba(47, 99, 255, 0.56), inset 0 0 14px rgba(115, 183, 255, 0.18);
  border-color: rgba(115, 183, 255, 0.86);
  color: #fff;
}

/* =========================================
   v0.6：Edge Lighting（局部生成，效能安全，見 js/fx.js spawnEdgeLight）
========================================= */
.edge-light-fx {
  position: absolute;
  width: 116px;
  height: 116px;
  transform: translate(-50%, -50%);
  border-radius: 20px;
  pointer-events: none;
  z-index: 10;
  opacity: 0;
}
.edge-light-fx.fx-basic {
  box-shadow: inset 0 0 20px var(--coreo-edge-basic), 0 0 10px var(--coreo-edge-basic);
  animation: edge-pulse-anim 0.6s cubic-bezier(0.25, 1, 0.5, 1) forwards;
}
/* v0.6.7：Core Pulse 不再用這個小型金色 edge-light，統一由 .supernova-burst-fx 表現，
   避免同一個拾取事件疊兩層視覺效果 */
@keyframes edge-pulse-anim {
  0% { opacity: 1; transform: translate(-50%, -50%) scale(0.5); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.1); }
}

/* =========================================
   v0.6：最簡化 Stage Select
========================================= */
#stage-select-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: var(--coreo-bg-base);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease;
}
#stage-select-overlay.show {
  opacity: 1;
  pointer-events: auto;
}
.stage-card {
  width: 240px;
  padding: 20px;
  margin: 10px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  text-align: center;
  color: var(--coreo-text-primary);
  cursor: pointer;
  transition: all 0.2s;
}
.stage-card.locked {
  opacity: 0.4;
  pointer-events: none;
  filter: grayscale(100%);
}
.stage-card:active {
  transform: scale(0.95);
}

/* =========================================
   Stage 02 Circuit Pulse (線性通電光效) — v0.8.0
   GPT 正式裁決：Core Pulse 回饋改成線性結構反應光，只影響 Stage02，
   Stage01 的 Supernova Burst + 白金矩陣線條不受影響。
   共用既有 .cell.wall::before／.cell.path::after 這兩個偽元素掛勾（跟 Stage01
   的 matrix-pulse 效果共用同一組插槽，靠 #world.circuit-pulse 與 #world.matrix-pulse
   互斥的觸發條件區分，不會同時生效），不新增 DOM，opacity/animation 驅動，效能安全。
========================================= */
#world.circuit-pulse .cell.wall.zone-vault::before,
#world.circuit-pulse .cell.wall.zone-return::before,
#world.circuit-pulse .cell.wall.zone-lure::before,
#world.circuit-pulse .cell.path::after {
  opacity: 0;
  z-index: 10;
}

/* Vault：強烈鈦白邊緣 + 冰青內發光 */
#world.circuit-pulse .cell.wall.zone-vault::before {
  box-shadow: inset 0 0 0 1px #F4F8FF, inset 0 0 8px #64D2FF;
  animation: circuit-flash 0.8s cubic-bezier(0.1, 0.9, 0.2, 1) forwards;
}

/* 回程與 Lure：冷色導光線，帶有節奏延遲 */
#world.circuit-pulse .cell.wall.zone-return::before {
  box-shadow: inset 0 0 0 1px #00F0FF, inset 0 0 4px #00F0FF;
  animation: circuit-flash-delayed 0.8s cubic-bezier(0.1, 0.9, 0.2, 1) forwards;
}
#world.circuit-pulse .cell.wall.zone-lure::before {
  box-shadow: inset 0 0 0 1px rgba(100, 210, 255, 0.6);
  animation: circuit-flash 0.8s cubic-bezier(0.1, 0.9, 0.2, 1) forwards;
}

/* 路線邊緣：極細微電流痕跡 */
#world.circuit-pulse .cell.path::after {
  background: rgba(100, 210, 255, 0.05);
  box-shadow: inset 0 0 1px #64D2FF;
  animation: circuit-flash 0.8s cubic-bezier(0.1, 0.9, 0.2, 1) forwards;
}

/* v0.8.4：Sean 反映原本的雙峰曲線視覺上只讀得出「閃一次」，改成 3 個乾淨的完全歸零再點亮
   循環，讓「電壓跳動 2~3 次」的效果真的看得出來是分開的閃爍，不是一條連續的亮度曲線 */
@keyframes circuit-flash {
  0% { opacity: 0; }
  8% { opacity: 1; }
  16% { opacity: 0; }
  24% { opacity: 1; }
  32% { opacity: 0; }
  42% { opacity: 0.85; }
  55% { opacity: 0.15; }
  100% { opacity: 0; }
}
@keyframes circuit-flash-delayed {
  0%, 15% { opacity: 0; }
  23% { opacity: 0.8; }
  31% { opacity: 0; }
  39% { opacity: 0.8; }
  47% { opacity: 0; }
  57% { opacity: 0.6; }
  70% { opacity: 0.1; }
  100% { opacity: 0; }
}

/* =========================================
   v0.9.0 Line-based Charging Sequence
   兩關共用 2.4 秒五段式線性充電；只動畫 opacity，不改整面底色。
========================================= */
.stage-02 .cell.wall.zone-vault::before,
.stage-02 .cell.wall.zone-lure::before,
.stage-02 .cell.wall.zone-return::before {
  opacity: 0.08;
  background: linear-gradient(90deg, transparent 4%, rgba(47, 99, 255, 0.7) 50%, transparent 96%);
}

#world.circuit-pulse .cell.path::after,
#world.circuit-pulse .cell.wall.zone-vault::before,
#world.circuit-pulse .cell.wall.zone-lure::before,
#world.circuit-pulse .cell.wall.zone-return::before {
  opacity: 0;
  z-index: 10;
  background: transparent;
}

#world.circuit-pulse .cell.path::after {
  box-shadow: inset 0 0 0 1px var(--coreo-s1-guide-secondary), inset 0 0 5px rgba(100, 210, 255, 0.28);
}
#world.stage-02.circuit-pulse .cell.path::after {
  box-shadow:
    inset 0 0 0 1px rgba(229, 243, 255, 0.9),
    inset 0 0 0 2px rgba(115, 183, 255, 0.7),
    inset 0 0 8px rgba(47, 99, 255, 0.48);
}
#world.circuit-pulse .cell.path.pulse-wave-1::after { animation: circuit-wave-1 2.4s linear forwards; }
#world.circuit-pulse .cell.path.pulse-wave-2::after { animation: circuit-wave-2 2.4s linear forwards; }
#world.circuit-pulse .cell.path.pulse-wave-3::after { animation: circuit-wave-3 2.4s linear forwards; }
#world.circuit-pulse .cell.path.pulse-wave-4::after { animation: circuit-wave-4 2.4s linear forwards; }
#world.circuit-pulse .cell.path.pulse-wave-5::after { animation: circuit-wave-5 2.4s linear forwards; }

#world.circuit-pulse .cell.wall.zone-vault::before {
  box-shadow: inset 0 0 0 1px var(--coreo-s2-highlight), inset 0 0 7px var(--coreo-s2-guide);
  animation: circuit-wave-2 2.4s linear forwards;
}
#world.circuit-pulse .cell.wall.zone-lure::before {
  box-shadow: inset 0 0 0 1px var(--coreo-s2-guide-secondary);
  animation: circuit-wave-3 2.4s linear forwards;
}
#world.circuit-pulse .cell.wall.zone-return::before {
  box-shadow: inset 0 0 0 1px var(--coreo-s2-tip), inset 0 0 5px rgba(115, 183, 255, 0.32);
  animation: circuit-wave-4 2.4s linear forwards;
}

/* v0.10.6.1 Stage02：只加強路線／牆緣通電辨識度，不碰 player、filter 或新增粒子。
   五段拓撲與 2.4 秒總長維持不變；較寬的峰值和短餘韻讓深鈷藍材質上也能清楚讀出傳導方向。 */
#world.stage-02.circuit-pulse .cell.path.pulse-wave-1::after { animation-name: circuit-wave-s2-1; }
#world.stage-02.circuit-pulse .cell.path.pulse-wave-2::after { animation-name: circuit-wave-s2-2; }
#world.stage-02.circuit-pulse .cell.path.pulse-wave-3::after { animation-name: circuit-wave-s2-3; }
#world.stage-02.circuit-pulse .cell.path.pulse-wave-4::after { animation-name: circuit-wave-s2-4; }
#world.stage-02.circuit-pulse .cell.path.pulse-wave-5::after { animation-name: circuit-wave-s2-5; }

#world.stage-02.circuit-pulse .cell.wall.zone-vault::before {
  box-shadow: inset 0 0 0 1px rgba(229, 243, 255, 0.92), inset 0 0 9px rgba(115, 183, 255, 0.58);
  animation-name: circuit-wave-s2-2;
}
#world.stage-02.circuit-pulse .cell.wall.zone-lure::before {
  box-shadow: inset 0 0 0 1px rgba(115, 183, 255, 0.88), inset 0 0 7px rgba(47, 99, 255, 0.42);
  animation-name: circuit-wave-s2-3;
}
#world.stage-02.circuit-pulse .cell.wall.zone-return::before {
  box-shadow: inset 0 0 0 1px rgba(229, 243, 255, 0.82), inset 0 0 8px rgba(115, 183, 255, 0.52);
  animation-name: circuit-wave-s2-4;
}

@keyframes circuit-wave-1 { 0%,3%{opacity:0} 4%,8%{opacity:1} 10%,100%{opacity:0} }
@keyframes circuit-wave-2 { 0%,13%{opacity:0} 15%,20%{opacity:1} 22%,100%{opacity:0} }
@keyframes circuit-wave-3 { 0%,27%{opacity:0} 29%,35%{opacity:.92} 37%,100%{opacity:0} }
@keyframes circuit-wave-4 { 0%,43%{opacity:0} 45%,52%{opacity:.88} 54%,100%{opacity:0} }
@keyframes circuit-wave-5 { 0%,62%{opacity:0} 65%,73%{opacity:.58} 78%,100%{opacity:0} }

@keyframes circuit-wave-s2-1 { 0%,2%{opacity:0} 4%,9%{opacity:1} 12%{opacity:.24} 16%,100%{opacity:0} }
@keyframes circuit-wave-s2-2 { 0%,11%{opacity:0} 14%,21%{opacity:1} 24%{opacity:.24} 28%,100%{opacity:0} }
@keyframes circuit-wave-s2-3 { 0%,25%{opacity:0} 28%,36%{opacity:.98} 39%{opacity:.22} 43%,100%{opacity:0} }
@keyframes circuit-wave-s2-4 { 0%,41%{opacity:0} 44%,53%{opacity:.94} 56%{opacity:.2} 60%,100%{opacity:0} }
@keyframes circuit-wave-s2-5 { 0%,59%{opacity:0} 63%,74%{opacity:.82} 78%{opacity:.18} 83%,100%{opacity:0} }

/* =========================================
   Stage 03 — SIPHON CIRCUIT
   全部以 Stage 03 專屬選擇器隔離，不改 Stage 01／02。
========================================= */
:root {
  /* Stage 03 牆面色改「紫水晶 Amethyst Violet #8D63D2」。
     原因：SIPHON 的身分色是綠，舊的綠牆讓反派整個融進背景（Sean 真機判定）。
     角色顏色是身分不該遷就關卡，所以讓牆讓路。紫是綠的對比色 → SIPHON 會直接跳出來。
     路面維持中性低飽和（亮度對齊 Stage01 #202936 / Stage02 #1D2634），飽和紫只用在牆框與能量線。 */
  --coreo-s3-path: #262231;
  --coreo-s3-path-metal: #3B3550;
  --coreo-s3-wall-top: #08060D;
  --coreo-s3-wall-side: #241F33;
  --coreo-s3-wall-shadow: rgba(6, 3, 14, .34);
  --coreo-s3-shell: #8D63D2;
  --coreo-s3-shell-hot: #F2EBFF;
  --coreo-s3-guide: #8D63D2;
  --coreo-s3-guide-secondary: #B79BEA;
  --coreo-s3-tip: #D6C6F7;
  --coreo-s3-highlight: #F2EBFF;
  --coreo-s3-core-basic: #EDE4FF;
  --coreo-s3-core-boost: #7A4BD0;
  --coreo-s3-core-boost-soft: #C3A8F2;
}

body.stage-03-active {
  background: linear-gradient(180deg, #08060D 0%, #050309 100%);
}
body.stage-03-active #fog-overlay {
  height: 14%;
  background: linear-gradient(to bottom, rgba(8, 5, 14, .88) 0%, rgba(8, 5, 14, .2) 68%, transparent 100%);
}
.hud-value.glow-s3 {
  color: var(--coreo-s3-highlight);
  text-shadow: 0 0 16px rgba(141, 99, 210, .8);
  transform: scale(1.2);
}

.stage-03 .cell.path {
  background: linear-gradient(145deg, rgba(59, 53, 80, .32), transparent 44%), var(--coreo-s3-path);
  box-shadow: inset 0 0 0 1px rgba(242, 235, 255, .06), inset 0 0 8px rgba(141, 99, 210, .08);
}
.stage-03 .cell.wall {
  border: 2px solid transparent;
  border-radius: 8px;
  background:
    linear-gradient(145deg, #150F22 0%, var(--coreo-s3-wall-top) 43%, #0A0713 76%, #171029 100%) padding-box,
    linear-gradient(145deg, var(--coreo-s3-shell-hot) 0%, #B79BEA 27%, #563593 58%, var(--coreo-s3-shell) 82%, #8D63D2 100%) border-box;
  transform: translateZ(18px) scale(.92);
  transform-origin: center;
  box-shadow:
    0 9px 20px var(--coreo-s3-wall-shadow),
    0 2px 7px rgba(141, 99, 210, .14),
    inset 0 0 0 1px #050310,
    inset 0 0 0 3px rgba(141, 99, 210, .92),
    inset 0 0 0 4px rgba(183, 155, 234, .62),
    inset 0 0 0 5px rgba(242, 235, 255, .42),
    inset 0 0 12px rgba(141, 99, 210, .14);
}
.stage-03 .cell.wall::after {
  bottom: -18px;
  left: 2px;
  width: calc(100% - 4px);
  height: 18px;
  background:
    linear-gradient(180deg, rgba(242, 235, 255, .16) 0 1px, transparent 2px),
    linear-gradient(180deg, #332A4D 0%, var(--coreo-s3-wall-side) 48%, #100B1C 100%);
  box-shadow: inset 0 1px 0 rgba(183, 155, 234, .2), 0 7px 13px var(--coreo-s3-wall-shadow), 0 2px 8px rgba(141, 99, 210, .1);
  border-radius: 0 0 5px 5px;
}
.stage-03 .cell.wall.zone-vault { filter: saturate(1.14) brightness(1.06); }
.stage-03 .cell.wall.zone-lure { filter: saturate(.92) brightness(.98); }
.stage-03 .cell.wall.zone-return { filter: saturate(1.04); }

.stage-03 .light-core-item.standard,
.stage-03 .light-core-item.basic {
  background: var(--coreo-s3-core-basic);
  box-shadow: 0 0 11px var(--coreo-s3-guide-secondary), 0 0 22px rgba(141, 99, 210, .22);
}
.stage-03 .light-core-item.upgraded,
.stage-03 .light-core-item.boost {
  background: radial-gradient(circle at 34% 28%, #FFFFFF 0 9%, #F2EBFF 10% 20%, transparent 21%), linear-gradient(145deg, #C3A8F2 0%, var(--coreo-s3-core-boost) 42%, #4A2A8C 76%, #22114A 100%);
  border: 1px solid rgba(242, 235, 255, .94);
  border-radius: 4px;
  box-shadow: 0 0 0 2px rgba(10, 5, 24, .94), 0 0 0 3px rgba(195, 168, 242, .68), 0 0 14px rgba(122, 75, 208, .8), 0 0 24px rgba(141, 99, 210, .26), inset 0 0 7px rgba(242, 235, 255, .5);
}

#enemy .actor-sprite.siphon {
  background-image: url('../assets/enemy_siphon.png');
  filter: drop-shadow(0 0 18px rgba(66, 184, 120, .95)) drop-shadow(0 0 42px rgba(66, 184, 120, .65));
}
/* SIPHON 維持綠色身分（名稱與光暈都不跟著牆變紫），在紫牆上形成最大對比 */
.siphon-name { color: #73E0A6; }

#stage-briefing.stage-03 .briefing-bg {
  background: linear-gradient(180deg, #0C0818 0%, #06040E 48%, #030208 100%);
}
#stage-briefing.stage-03 .bg-glow-player,
#stage-briefing.stage-03 .bg-glow-ember {
  background: radial-gradient(circle, rgba(141, 99, 210, .2) 0%, rgba(122, 75, 208, .07) 40%, transparent 70%);
}
#stage-briefing.stage-03 .briefing-header h2,
#stage-briefing.stage-03 .info-row p strong { color: var(--coreo-s3-highlight); }
#stage-briefing.stage-03 .briefing-header p,
#stage-briefing.stage-03 .info-row p { color: var(--coreo-s3-tip); }
#stage-briefing.stage-03 .info-mission p { color: rgba(242, 235, 255, .9); }
#stage-briefing.stage-03 .pulse-icon { background: var(--coreo-s3-core-boost); box-shadow: 0 0 8px var(--coreo-s3-core-boost-soft); }
#stage-briefing.stage-03 .shard-icon { background: var(--coreo-s3-core-basic); box-shadow: 0 0 8px var(--coreo-s3-guide-secondary); }
#stage-briefing.stage-03 #briefing-enter-btn {
  background: linear-gradient(180deg, rgba(141, 99, 210, .06), transparent);
  border-color: rgba(141, 99, 210, .66);
  color: var(--coreo-s3-highlight);
  box-shadow: inset 0 0 0 1px rgba(183, 155, 234, .06);
}
#stage-briefing.stage-03 #briefing-enter-btn:active {
  box-shadow: 0 0 22px rgba(141, 99, 210, .56), inset 0 0 14px rgba(183, 155, 234, .18);
}
#level-complete-overlay.stage-03 .lc-line {
  background: linear-gradient(90deg, var(--coreo-s3-guide), var(--coreo-s3-highlight));
}

.stage-03 .cell.wall.zone-vault::before,
.stage-03 .cell.wall.zone-lure::before,
.stage-03 .cell.wall.zone-return::before {
  opacity: .18;
  background: linear-gradient(90deg, transparent 4%, rgba(141, 99, 210, .72) 50%, transparent 96%);
}
/* 通電：Sean 真機回報「吃到光源效果不夠」→ 提高亮度與擴散半徑，只動路面/牆緣，不加重主角 */
#world.stage-03.circuit-pulse .cell.path::after {
  box-shadow:
    inset 0 0 0 1px rgba(242, 235, 255, .98),
    inset 0 0 0 2px rgba(183, 155, 234, .88),
    inset 0 0 14px rgba(141, 99, 210, .78),
    0 0 12px rgba(141, 99, 210, .42);
}
#world.stage-03.circuit-pulse .cell.wall.zone-vault::before {
  box-shadow: inset 0 0 0 1px var(--coreo-s3-highlight), inset 0 0 9px var(--coreo-s3-guide-secondary);
  animation-name: circuit-wave-s2-2;
}
#world.stage-03.circuit-pulse .cell.wall.zone-lure::before {
  box-shadow: inset 0 0 0 1px var(--coreo-s3-guide-secondary), inset 0 0 11px rgba(141, 99, 210, .72);
  animation-name: circuit-wave-s2-3;
}
#world.stage-03.circuit-pulse .cell.wall.zone-return::before {
  box-shadow: inset 0 0 0 1px var(--coreo-s3-tip), inset 0 0 12px rgba(183, 155, 234, .78);
  animation-name: circuit-wave-s2-4;
}
