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

[hidden] { display: none !important; }

/* ── Base ──────────────────────────────────────────────────── */
html {
  height: -webkit-fill-available;
}
body {
  font-family: 'Noto Sans TC', 'PingFang TC', sans-serif;
  background: #fec804;
  color: #333;
  height: 100dvh;          /* dvh 計入瀏覽器工具列，避免被壓縮 */
  height: -webkit-fill-available;
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* ── 橫向提示 ──────────────────────────────────────────────── */
#rotate-notice {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: #fec804;
  color: #000000;
  align-items: center;
  justify-content: center;
  text-align: center;
}

@media screen and (orientation: landscape) {
  body { overflow: hidden; }
  #app { display: none; }
  #rotate-notice { display: flex; }
}

.rotate-inner { padding: 24px; text-align: center; }
#rotate-logo {
  width: 100px;
  height: 100px;
  object-fit: contain;
  margin-bottom: 16px;
  animation: logoShake 0.8s ease-in-out infinite;
}
.rotate-inner p { font-size: 16px; color: #000000; }

/* ── App 容器 ────────────────────────────────────────────── */
#app {
  max-width: 480px;
  margin: 0 auto;
  height: 100dvh;
  overflow: hidden;
  background: #fec804;
  display: flex;
  flex-direction: column;
}

/* ── 載入 / 錯誤 ──────────────────────────────────────────── */
#loading, #error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100dvh;
  gap: 16px;
  padding: 32px 24px;
  text-align: center;
  background: #fec804;
}

/* ⚠️ AB主題（中秋節）專屬樣式，全部掛在「body.skin-ab」這個class下，
   只有卡片資料skin_code==='AB'時，JS才會幫<body>加上這個class，
   AA（預設/無主題）卡片完全不受影響、維持原本黃底樣式（2026-09-06二次修正：
   第一次修正只把class掛在#loading本身，但body自己的底色/安全區塊還是寫死黑色
   影響到AA，這次改成class掛在body上，body的底色也一併改成class條件式，
   往後每一層新增素材都要記得掛在body.skin-ab下，不要直接寫body或#loading） */
body.skin-ab {
  /* body本身背景只會在各畫面容器沒完全蓋住的安全區域（瀏海/狀態列）縫隙露出，
     AB主題時改黑跟夜空背景一致；AA維持前面body{background:#fec804}的黃色不受影響 */
  background: #000000;
}

/* 第一層：夜空底圖 */
body.skin-ab #loading {
  position: relative;
  /* z-index:0（配合position:relative）讓#loading自己建立堆疊層級（stacking context），
     否則子層::before的z-index:-1會直接跑到#loading自己的背景圖底下完全被蓋住看不見
     （常見CSS陷阱：negative z-index的偽元素若父層沒有形成stacking context會失效） */
  z-index: 0;
  background-color: #000000;
  background-image: url('skins/AB_loading_bg.png');
  background-size: cover;
  background-position: center;
}

/* 第2層：閃爍星星，純CSS radial-gradient畫白色小圓點（原本用AB_loading_stars.png
   疊圖，因為跟底圖001太相似肉眼分辨不出透明度變化，已改用程式碼畫的星點取代） */
body.skin-ab #loading::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  background-image:
    radial-gradient(1.5px 1.5px at 8% 12%,  #fff, transparent 70%),
    radial-gradient(2px   2px   at 18% 28%, #fff, transparent 70%),
    radial-gradient(1px   1px   at 27% 8%,  #fff, transparent 70%),
    radial-gradient(2px   2px   at 35% 45%, #fff, transparent 70%),
    radial-gradient(1.5px 1.5px at 44% 18%, #fff, transparent 70%),
    radial-gradient(1px   1px   at 52% 33%, #fff, transparent 70%),
    radial-gradient(2px   2px   at 61% 10%, #fff, transparent 70%),
    radial-gradient(1.5px 1.5px at 70% 24%, #fff, transparent 70%),
    radial-gradient(1px   1px   at 78% 6%,  #fff, transparent 70%),
    radial-gradient(2px   2px   at 85% 20%, #fff, transparent 70%),
    radial-gradient(1.5px 1.5px at 92% 38%, #fff, transparent 70%),
    radial-gradient(1px   1px   at 15% 52%, #fff, transparent 70%),
    radial-gradient(2px   2px   at 30% 60%, #fff, transparent 70%),
    radial-gradient(1.5px 1.5px at 48% 55%, #fff, transparent 70%),
    radial-gradient(1px   1px   at 65% 48%, #fff, transparent 70%),
    radial-gradient(2px   2px   at 80% 58%, #fff, transparent 70%),
    radial-gradient(1.5px 1.5px at 10% 70%, #fff, transparent 70%),
    radial-gradient(1px   1px   at 40% 75%, #fff, transparent 70%),
    radial-gradient(2px   2px   at 58% 68%, #fff, transparent 70%),
    radial-gradient(1.5px 1.5px at 88% 72%, #fff, transparent 70%);
  background-repeat: no-repeat;
  opacity: 0;
  animation: abLoadingStarsTwinkle 1s ease-in-out infinite;
  pointer-events: none;
}

/* 第3~5層：雲朵裝飾（004~007＝第3層）＋008（第4層）＋009（第5層），疊在
   第2層星星之上、logo/文字之下。2026-09-06改版：原本用::after多重
   background-image疊放（見git歷史），但那個寫法所有圖層共用同一個
   background-size，沒辦法讓每張雲各自獨立縮放動畫、也沒辦法錯開時間。
   改成6個真實的<div class="ab-cloud ab-cloud-XXX">（需要在HTML裡的
   #loading內新增，見nfc.html/nfc-rate.html/index.html/app_nfc.html/
   rate.html/app_nfc_rate.html六個檔案），每個各自套用transform:scale()
   動畫，用animation-delay錯開，才能做到「漸漸放大縮小、慢慢飄動、
   互相不同步」的效果。z-index:-1、position:absolute皆與#loading同一個
   堆疊層級（沿用#loading的position:relative;z-index:0），確保蓋在星星
   之上、logo文字之下。DOM順序＝疊放順序（同z-index時後面的在上面），
   由後到前依序放：004,005,006,007(L3，同層彼此順序不重要)→008(L4)→
   009(L5，最上面) */
body.skin-ab #loading .ab-cloud {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  pointer-events: none;
}
body.skin-ab #loading .ab-cloud-004 {
  background-image: url('skins/AB_loading_L3_004.png');
  animation: abCloudDrift 18s ease-in-out infinite;
}
body.skin-ab #loading .ab-cloud-005 {
  background-image: url('skins/AB_loading_L3_005.png');
  animation: abCloudDrift 21s ease-in-out infinite -4.6s;
}
body.skin-ab #loading .ab-cloud-006 {
  background-image: url('skins/AB_loading_L3_006.png');
  animation: abCloudDrift 16.8s ease-in-out infinite -8.2s;
}
body.skin-ab #loading .ab-cloud-007 {
  background-image: url('skins/AB_loading_L3_007.png');
  animation: abCloudDrift 22.4s ease-in-out infinite -3.2s;
}
body.skin-ab #loading .ab-cloud-008 {
  background-image: url('skins/AB_loading_L4_008.png');
  animation: abCloudDrift 19.4s ease-in-out infinite -7s;
}
body.skin-ab #loading .ab-cloud-009 {
  background-image: url('skins/AB_loading_L5_009.png');
  animation: abCloudDrift 20s ease-in-out infinite -10.4s;
}
/* 每張雲各自1~1.08倍慢慢縮放，搭配不同animation-duration／負值animation-delay
   （負值delay＝動畫一開始就從時間軸中段播放，避免6張雲同時從頭開始而看起來一致） */
@keyframes abCloudDrift {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.08); }
}

/* 第6層：010.png Sprite Sheet（3幀，每幀74x98px，橫向排列於0,0／74,0／148,0）。
   2026-09-06改版：原本是flex文件流子項（排在文字下方），現在改成絕對定位、
   固定貼齊背景月亮下緣，位置由JS即時計算（position_ab_sprite()，見
   main.js/app_nfc.js、rate.js/app_nfc_rate.js、nfc.html、nfc-rate.html），
   用跟CSS background-size:cover完全相同的縮放公式換算月亮在畫面上的實際
   座標，才能保證不同手機螢幕尺寸下兔子都精準貼在月亮上不跑位（純CSS
   百分比定位無法做到這件事，因為cover裁切量會隨長寬比變動）。
   scale(0.5)＝縮小1倍（變成原本一半大）。用steps(1)讓每個keyframe區間
   瞬間切換不做過渡動畫，才會是逐格sprite效果而不是滑動。序列
   1→2→3→2→1→2→3→2...：4個等分區間剛好對應0%=幀1,25%=幀2,50%=幀3,
   75%=幀2,100%=幀1(=下一輪的0%接續播放) */
body.skin-ab #loading .ab-sprite {
  position: absolute;
  top: 0;
  left: 0;
  width: 74px;
  height: 98px;
  z-index: 1;
  background-image: url('skins/AB_loading_L6_sprite.png');
  background-repeat: no-repeat;
  background-position: 0 0;
  animation: abSpriteHop 0.8s steps(1) infinite;
  pointer-events: none;
}
@keyframes abSpriteHop {
  0%   { background-position: 0px 0; }    /* 幀1 */
  25%  { background-position: -74px 0; }  /* 幀2 */
  50%  { background-position: -148px 0; } /* 幀3 */
  75%  { background-position: -74px 0; }  /* 幀2 */
  100% { background-position: 0px 0; }    /* 幀1，接續下一輪 */
}

/* logo上移、文字下移+改白字（僅AB主題） */
body.skin-ab #loading #loading-logo {
  margin-top: -200px;
}
body.skin-ab #loading p {
  color: #ffffff;
  margin-top: 0;
}

@keyframes abLoadingStarsTwinkle {
  0%, 100% { opacity: 0; }
  50%      { opacity: 1; }
}

/* AB主題（及未來IP主題）專用：在頂部配率列(#stats-bar)與下方格子容器
   (#card-area／#rate-body)之間，預留約1格高度的空白區塊放IP素材。
   AA完全不留空（display:none），只有body.skin-ab才顯示佔位、擠壓下方
   格子容器高度（#card-area／#rate-body都是flex:1，這裡多一個固定比例
   的flex child，flexbox會自動把剩餘空間讓出來，不需要另外手動縮小
   格子容器）。aspect-ratio:5/1 是「5欄格子排版下1列正方形格子的高度」
   近似值（格子本身aspect-ratio:1，5欄寬對1列高，忽略gap微小誤差），
   寬度撐滿容器時高度等比例縮放，不受手機螢幕尺寸影響。
   2026-09-06：原本5/2（2格高）使用者反饋太空，改為5/1（1格高） */
.ip-space {
  display: none;
}
body.skin-ab .ip-space {
  display: block;
  width: 100%;
  aspect-ratio: 5 / 1;
  flex-shrink: 0;
}

/* AB主題：格子容器白底改為20%不透明度（讓底下的IP主題背景透出來），
   #rate-card是配率頁的白卡、.card-page是刮刮卡頁的白卡，選擇器特異性
   比各頁面自己inline定義的#rate-card{background:white}／.card-page
   （style.css共用）都高，會正確覆蓋，不需要動到各頁面原本的定義 */
body.skin-ab #rate-card,
body.skin-ab .card-page {
  background: rgba(255, 255, 255, 0.1);
}

#loading p { font-size: 15px; color: #000000; }
.sub-text { font-size: 13px; color: #999; }
.state-icon { font-size: 64px; }

/* ── 無刮刮紙（與nfc-rate.html #no-card統一：LOGO＋文字置中＋底部廣告橫幅） ── */
#no-card {
  display: flex;
  flex-direction: column;
  height: 100dvh;
  padding: 0;
  gap: 0;
  background: #fec804;
}

#no-card-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 32px 24px;
  text-align: center;
}

#no-card-body p {
  font-size: 30px;
  font-weight: bold;
  color: #000000;
}

#no-card-logo {
  width: 120px;
  height: 120px;
  object-fit: contain;
  animation: logoShake 0.8s ease-in-out infinite;
}

#rate-footer {
  flex-shrink: 0;
  background: #fec804;
}

/* 載入 logo 搖晃 */
#loading-logo {
  width: 120px;
  height: 120px;
  object-fit: contain;
  animation: logoShake 0.8s ease-in-out infinite;
}
@keyframes logoShake {
  0%, 100% { transform: rotate(0deg); }
  20%       { transform: rotate(-15deg); }
  40%       { transform: rotate(15deg); }
  60%       { transform: rotate(-10deg); }
  80%       { transform: rotate(10deg); }
}

.spinner {
  width: 44px;
  height: 44px;
  border: 4px solid #ddd;
  border-top-color: #d42d25;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

#error p { font-size: 15px; color: #a82020; }
#error button {
  background: #d42d25;
  color: white;
  border: none;
  border-radius: 10px;
  padding: 12px 32px;
  font-size: 15px;
  cursor: pointer;
  margin-top: 8px;
}

/* ── 主遊戲（flex column，佔滿整個 dvh） ─────────────────── */
#game {
  display: flex;
  flex-direction: column;
  height: 100dvh;
  overflow: hidden;
}

/* ── 頂部：中獎配率資訊 ──────────────────────────────────── */
#stats-bar {
  background: #000000;
  /* safe-area-inset-top：讓黑色背景延伸填滿 iPhone 狀態列，避免黃色透出 */
  padding: calc(8px + env(safe-area-inset-top, 0px)) 12px 6px;
  border-bottom: 1px solid rgba(255,255,255,0.2);
  flex-shrink: 0;
  box-shadow: 0 1px 4px rgba(0,0,0,0.06);
}

#prize-list-wrapper {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 6px;
}

.prize-scroll-arrow {
  color: white;
  font-size: 22px;
  font-weight: bold;
  flex-shrink: 0;
  line-height: 1;
  opacity: 0.8;
}

#prize-list {
  flex: 1;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  gap: 5px;
  height: 52px;          /* 固定兩排高度 */
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;       /* Firefox */
  -ms-overflow-style: none;    /* IE */
}
#prize-list::-webkit-scrollbar {
  display: none;               /* Chrome / Safari */
}

.prize-chip {
  background: #fec804;
  color: #000000;
  border-radius: 12px;
  padding: 3px 9px;
  font-size: 11px;
  white-space: nowrap;
}
.prize-chip.won {
  background: #555;
  color: #aaa;
  text-decoration: line-through;
}

#stats-row {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 2px;
  font-size: 14px;
  color: white;
  border-top: 1px solid rgba(255,255,255,0.2);
  padding-top: 5px;
}

/* ── 刮刮紙格子區（彈性填滿） ───────────────────────────── */
#card-area {
  flex: 1;
  overflow: hidden;
  padding: 10px 14px 10px;
  min-height: 0;
  position: relative;
}

#pages-wrapper {
  height: 100%;
}

.card-page {
  height: 100%;
  background: white;
  border-radius: 14px;
  padding: 10px 10px 6px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.12);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* 格子 Grid（單頁垂直滑動） */
.slot-grid {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 4px;
  align-content: start;
}

/* ── 格子 ────────────────────────────────────────────────── */
.slot {
  aspect-ratio: 1;
  border-radius: 6px;
  overflow: hidden;
  position: relative;
  cursor: pointer;
  background: #000000;
}

.slot-empty {
  aspect-ratio: 1;
}

/* 底層內容（中獎 / 未中獎） */
.slot-content {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 2px;
}

.slot-prize { background: linear-gradient(135deg, #a82020, #d42d25); }
.slot-no-prize { background: #ebebeb; }

.prize-name-display {
  font-weight: bold;
  color: #fff;
  text-align: center;
  word-break: break-all;
  line-height: 1.25;
  padding: 2px;
}
.no-prize-mark {
  font-size: 48px;
  color: #d42d25;
  line-height: 1;
  margin-bottom: 14px;
}

/* Canvas 遮罩（未刮開） */
.scratch-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  cursor: pointer;
  border-radius: 6px;
}

/* 已刮開未中獎：底層略暗 */
.slot.scratched.no-prize .slot-content {
  opacity: 0.55;
}

/* ── 遊戲結束遮罩 ─────────────────────────────────────────── */
#finish-overlay {
  position: absolute;
  inset: 0;
  background: rgba(212, 45, 37, 0.88);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 14px;
  z-index: 10;
  animation: pop-in 0.3s ease;
}

#finish-overlay .finish-text {
  color: white;
  font-size: 20px;
  font-weight: bold;
  text-align: center;
  line-height: 1.6;
  padding: 16px;
}

@keyframes pop-in {
  from { transform: scale(0.85); opacity: 0; }
  to   { transform: scale(1);    opacity: 1; }
}

/* ── Session 驗證遮罩 ─────────────────────────────────────── */
#session-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  background: #fec804;
  display: flex;
  align-items: center;
  justify-content: center;
}

#session-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

#session-msg {
  font-size: 16px;
  font-weight: bold;
  color: #000;
  text-align: center;
}

/* ── 刮獎密碼畫面 + 夾N刮N 各頁（claw 身份） ────────────── */
#scratch-password-screen,
#claw-input-screen,
#claw-quota-screen,
#claw-topup-screen,
#claw-done-overlay {
  position: fixed;
  inset: 0;
  z-index: 1850;
  background: #fec804;
  display: flex;
  align-items: center;
  justify-content: center;
}

.claw-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 80%;
  max-width: 320px;
}

#scratch-password-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 80%;
  max-width: 320px;
}

#scratch-password-title {
  font-size: 18px;
  font-weight: bold;
  color: #000;
  margin-bottom: 20px;
  text-align: center;
}

#scratch-password-input,
#claw-input-field {
  width: 100%;
  padding: 14px 16px;
  font-size: 22px;
  text-align: center;
  border: 2px solid #000;
  border-radius: 10px;
  background: #fff;
  outline: none;
  margin-bottom: 12px;
  box-sizing: border-box;
}

#scratch-password-input {
  letter-spacing: 4px;
}

#scratch-password-btn,
#claw-input-btn,
#claw-quota-btn,
#claw-done-btn {
  width: 100%;
  padding: 14px;
  font-size: 16px;
  font-weight: bold;
  background: #000;
  color: #fff;
  border: none;
  border-radius: 10px;
  cursor: pointer;
}

#claw-topup-back {
  flex: 1;
  padding: 14px 0;
  font-size: 16px;
  font-weight: bold;
  background: #06c755 !important;
  color: #fff !important;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

#claw-topup-start {
  flex: 1;
  padding: 14px 0;
  font-size: 16px;
  font-weight: bold;
  background: #000 !important;
  color: #fff !important;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

#scratch-password-error,
#claw-input-error {
  margin-top: 12px;
  font-size: 14px;
  font-weight: bold;
  color: #d42d25;
}

#scratch-password-hint {
  margin-top: 16px;
  font-size: 14px;
  font-weight: bold;
  color: #000;
  text-align: center;
}

/* ── 密碼輸入畫面 ─────────────────────────────────────────── */
#password-screen {
  position: fixed;
  inset: 0;
  z-index: 1900;
  background: #fec804;
  display: flex;
  align-items: center;
  justify-content: center;
}

#password-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 80%;
  max-width: 320px;
}

#password-hint-text {
  font-size: 18px;
  font-weight: bold;
  color: #000;
  margin-bottom: 20px;
  text-align: center;
}

#password-input {
  width: 100%;
  padding: 14px 16px;
  font-size: 22px;
  letter-spacing: 4px;
  text-align: center;
  border: 2px solid #000;
  border-radius: 10px;
  background: #fff;
  outline: none;
  margin-bottom: 12px;
}

#password-btn {
  width: 100%;
  padding: 14px;
  font-size: 16px;
  font-weight: bold;
  background: #000;
  color: #fff;
  border: none;
  border-radius: 10px;
  cursor: pointer;
}

#password-error {
  margin-top: 12px;
  font-size: 14px;
  font-weight: bold;
  color: #d42d25;
}

#password-bottom-hint {
  margin-top: 16px;
  font-size: 14px;
  font-weight: bold;
  color: #000;
  text-align: center;
}

/* ── 冷卻彈窗 ─────────────────────────────────────────────── */
#cooldown-overlay {
  position: fixed;
  inset: 0;
  z-index: 500;
  background: rgba(0,0,0,0.45);
  display: flex;
  align-items: center;
  justify-content: center;
}

#cooldown-box {
  background: white;
  border-radius: 16px;
  padding: 28px 36px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.2);
}

#cooldown-logo {
  width: 80px;
  height: 80px;
  object-fit: contain;
  animation: logoShake 0.8s ease-in-out infinite;
}

#cooldown-box p {
  font-size: 16px;
  font-weight: bold;
  color: #000;
}

#cooldown-count {
  font-size: 28px;
  font-weight: bold;
  color: #d42d25;
}

/* ── 導航列 ──────────────────────────────────────────────── */
#nav-row {
  display: flex;
  align-items: center;
  justify-content: center;
  /* safe-area-inset-bottom：為 iPhone home indicator 留空，避免按鈕被遮 */
  padding: 0 14px env(safe-area-inset-bottom, 0px);
  gap: 8px;
  flex-shrink: 0;
  background: #fec804;
}

#ad-space {
  flex: 1;
  height: 85px;
  align-self: center;
  border-radius: 6px;
  /* 不用 overflow:hidden，iOS Safari 的 overflow:hidden 會凍結 GIF 第一格 */
  display: flex;
  align-items: center;
  justify-content: center;
}

#ad-space a {
  display: flex !important;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

#ad-space video {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

/* ── 中獎彈窗 ─────────────────────────────────────────────── */
#modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 1025;
  background: rgba(0, 0, 0, 0.65);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

#modal {
  background: white;
  border-radius: 20px;
  padding: 28px 24px 20px;
  max-width: 320px;
  width: 100%;
  text-align: center;
  box-shadow: 0 8px 32px rgba(0,0,0,0.25);
  animation: modalIn 0.25s ease;
}
@keyframes modalIn {
  from { transform: scale(0.85); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

#modal-machine-name {
  font-size: 14px;
  font-weight: bold;
  color: #555;
  margin-bottom: 4px;
}
#modal-machine-name[hidden] { display: none; }

#modal-title {
  font-size: 24px;
  font-weight: bold;
  margin-bottom: 14px;
}

#modal-prize-image {
  margin-bottom: 12px;
}
#modal-prize-image[hidden] { display: none; }
#modal-prize-img {
  width: 100%;
  max-width: 100%;
  height: auto;
  object-fit: contain;
  border-radius: 10px;
  border: 2px solid #FEC804;
  display: block;
  margin: 0 auto;
}

#modal-prize-name {
  font-size: 20px;
  color: #d42d25;
  font-weight: bold;
  margin-bottom: 10px;
}

#modal-message {
  font-size: 16px;
  color: #d42d25;
  font-weight: bold;
  margin-bottom: 8px;
  word-break: break-all;
}

#modal-footer {
  font-size: 13px;
  color: #888;
  margin-bottom: 18px;
  line-height: 1.5;
}

#modal-line-section {
  margin-bottom: 14px;
  text-align: center;
}
#modal-line-section[hidden] { display: none; }

#modal-line-btn-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

#modal-line-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  background: #06c755;
  color: #fff;
  text-decoration: none;
  padding: 16px 24px;
  border-radius: 16px;
  font-size: 22px;
  font-weight: bold;
  flex: 1;
}

#modal-line-hint {
  font-size: 14px;
  color: #06C755;
  font-weight: bold;
  margin-top: 8px;
}

.modal-line-finger {
  font-size: 28px;
  display: inline-block;
}
.modal-line-finger-left  { animation: fingerLeft  1s ease-in-out infinite; }
.modal-line-finger-right { animation: fingerRight 1s ease-in-out infinite; }
@keyframes fingerLeft {
  0%,100% { transform: translateX(0); }
  50%      { transform: translateX(6px); }
}
@keyframes fingerRight {
  0%,100% { transform: translateX(0); }
  50%      { transform: translateX(-6px); }
}

#modal-btn {
  background: #0267b9;
  color: white;
  border: none;
  border-radius: 10px;
  padding: 13px;
  font-size: 16px;
  cursor: pointer;
  width: 100%;
  font-weight: bold;
}
#modal-btn:active { background: #0054a6; }
#modal-btn:disabled {
  background: #bbb;
  cursor: default;
}

/* ── 刮格確認彈窗 canvas 預覽 ──────────────────────────────── */
#scratch-confirm-canvas {
  display: block;
  margin: 0 auto 12px;
  border-radius: 10px;
  width: 90px;
  height: 90px;
}

/* ── 互動刮刮彈窗 ──────────────────────────────────────────── */
#scratch-play-overlay {
  position: fixed;
  inset: 0;
  z-index: 1020;
  background: rgba(255,255,255,0.60);
  display: flex;
  align-items: center;
  justify-content: center;
}

#scratch-play-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 16px;
  width: 100%;
}

/* 倒數數字覆蓋層（疊在黑色 canvas 上，置中顯示） */
#scratch-play-cd-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  z-index: 2;
  border-radius: 16px;
}

.sp-cd-num {
  font-size: 96px;
  font-weight: bold;
  color: #FFD700;
  text-shadow:
    -2px -2px 0 #000,  2px -2px 0 #000,
    -2px  2px 0 #000,  2px  2px 0 #000;
  line-height: 1;
}

/* bounce 動畫（↓用手滑動刮開格子↓） */
@keyframes bounce-ud {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(-6px); }
}

.sp-hint-bounce {
  animation: bounce-ud 0.8s ease-in-out infinite;
}

/* 波浪載入動畫（驗證刮刮格資料中...） */
@keyframes waveChar {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(-7px); }
}
.wave-char {
  display: inline-block;
  animation: waveChar 0.9s ease-in-out infinite;
}

/* sp-hint-normal：黑邊黃字粗體（一般提示） */
.sp-hint-normal {
  font-size: 18px;
  font-weight: bold;
  color: #FFD700;
  text-align: center;
  text-shadow:
    -1px -1px 0 #000,  1px -1px 0 #000,
    -1px  1px 0 #000,  1px  1px 0 #000;
}

/* sp-hint-countdown：倒數大數字 */
.sp-hint-countdown {
  font-size: 56px;
  font-weight: bold;
  color: #FFD700;
  text-align: center;
  text-shadow:
    -2px -2px 0 #000,  2px -2px 0 #000,
    -2px  2px 0 #000,  2px  2px 0 #000;
  line-height: 1;
}

#scratch-play-hint {
  min-height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
}

#scratch-play-slot {
  position: relative;
  width: min(74vw, 288px);
  height: min(74vw, 288px);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 6px 28px rgba(0,0,0,0.7);
}

#scratch-play-content {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 8px;
  background: #fff !important;
}
/* 刮刮彈窗內獎品文字改深色（底層為白色，避免透出） */
#scratch-play-content .prize-name-display {
  color: #d42d25;
}

#scratch-play-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  touch-action: none;
  cursor: crosshair;
  border-radius: 16px;
}

#scratch-play-instant-btn {
  background: #0267b9;
  color: #fff;
  border: none;
  border-radius: 10px;
  padding: 13px 28px;
  font-size: 16px;
  font-weight: bold;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0,0,0,0.35);
  margin-top: 24px;
}
#scratch-play-instant-btn:active { background: #0054a6; }
#scratch-play-instant-btn:disabled { background: #aaa; cursor: default; box-shadow: none; }

/* ── 刮格確認彈窗 ──────────────────────────────────────────── */
#scratch-confirm-overlay {
  position: fixed;
  inset: 0;
  z-index: 1010;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

#scratch-confirm-box {
  background: white;
  border-radius: 16px;
  padding: 28px 20px 20px;
  max-width: 280px;
  width: 100%;
  text-align: center;
  box-shadow: 0 8px 32px rgba(0,0,0,0.3);
  animation: modalIn 0.2s ease;
}

#scratch-confirm-text {
  font-size: 20px;
  font-weight: bold;
  color: #333;
  margin-bottom: 20px;
}

#scratch-confirm-btns {
  display: flex;
  gap: 10px;
}

#scratch-confirm-cancel {
  flex: 1;
  background: #eee;
  color: #333;
  border: none;
  border-radius: 10px;
  padding: 12px;
  font-size: 15px;
  font-weight: bold;
  cursor: pointer;
}
#scratch-confirm-cancel:active { background: #ddd; }

#scratch-confirm-ok {
  flex: 1;
  background: #0267b9;
  color: white;
  border: none;
  border-radius: 10px;
  padding: 12px;
  font-size: 15px;
  font-weight: bold;
  cursor: pointer;
}
#scratch-confirm-ok:active { background: #0054a6; }

/* ── 關閉確認彈窗 ──────────────────────────────────────────── */
#close-confirm-overlay {
  position: fixed;
  inset: 0;
  z-index: 1030;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

#close-confirm-box {
  background: white;
  border-radius: 16px;
  padding: 24px 20px 18px;
  max-width: 280px;
  width: 100%;
  text-align: center;
  box-shadow: 0 8px 32px rgba(0,0,0,0.3);
  animation: modalIn 0.2s ease;
}

#close-confirm-icon {
  font-size: 28px;
  margin-bottom: 10px;
}

#close-confirm-text {
  font-size: 14px;
  color: #333;
  line-height: 1.6;
  margin-bottom: 18px;
}

#close-confirm-btns {
  display: flex;
  gap: 10px;
}

#close-confirm-cancel {
  flex: 1;
  background: #eee;
  color: #333;
  border: none;
  border-radius: 10px;
  padding: 12px;
  font-size: 15px;
  font-weight: bold;
  cursor: pointer;
}
#close-confirm-cancel:active { background: #ddd; }

#close-confirm-ok {
  flex: 1;
  background: #d42d25;
  color: white;
  border: none;
  border-radius: 10px;
  padding: 12px;
  font-size: 15px;
  font-weight: bold;
  cursor: pointer;
}
#close-confirm-ok:active { background: #b52020; }

/* ══════════════════════════════════════════════════════════════
   促銷系統專屬新增（2026-09-09，見PROMO_SPEC.md第八/九節）
   ══════════════════════════════════════════════════════════════ */

/* 序號輸入框：格式SHOPEE-XXXXXXXXXX共18碼，沿用#password-input但letter-spacing
   縮小、字級縮小才放得下，覆蓋原本8位數密碼設計的樣式。
   錯誤文字要顯示在輸入框「內」（見PROMO_SPEC.md第70行），改成外層
   #password-input-wrap承接原本input的邊框/背景/圓角，input本身變透明無邊框，
   #password-error放在同一個wrap容器裡、緊接在input下方，視覺上仍是同一個框 */
#password-input-wrap {
  width: 100%;
  border: 2px solid #000;
  border-radius: 10px;
  background: #fff;
  margin-bottom: 12px;
  overflow: hidden;
}
#password-input {
  box-sizing: border-box;
  width: 100%;
  font-size: 16px;
  letter-spacing: 1px;
  border: none;
  border-radius: 0;
  background: transparent;
  margin-bottom: 0;
}
#password-error {
  margin: 0;
  padding: 0 16px 10px;
  text-align: center;
}

/* 促銷專屬背景（使用者已提供美術素材promo_bg_1.png／promo_bg_2.png，1080x2340
   直向全螢幕圖，兩張互為一組「1秒無限循環」動畫）。套用範圍：序號輸入頁、
   驗證中/載入/網路錯誤畫面、強制退出覆蓋層，四個畫面共用同一組背景動畫。
   ⚠️ 不直接對background-image做關鍵影格動畫（實測瀏覽器不會正確重繪，畫面
   維持黑底不換圖），改用AB主題既有驗證過的手法：兩個偽元素各疊一張圖，
   animate opacity 0/1切換（opacity是標準可動畫屬性，穩定可靠）。偽元素
   z-index:-1要蓋在內容之下，父層需要position+z-index才能正確建立堆疊層級
   （同AB主題#loading::before的既有寫法，見nfc_v2.0/web/style.css）。 */
#loading,
#error {
  position: relative; /* 原本沒有position，補上才能讓z-index:-1偽元素正確定位 */
  z-index: 0;
  background-color: #000000;
}
#password-screen,
#session-overlay {
  /* 這兩個選擇器原本就是position:fixed（見前面對應區塊），不可覆蓋，
     只需要補z-index:0讓fixed本身的堆疊層級正確接住z-index:-1的偽元素 */
  z-index: 0;
  background-color: #000000;
}
#loading::before, #loading::after,
#password-screen::before, #password-screen::after,
#session-overlay::before, #session-overlay::after,
#error::before, #error::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-size: cover;
  background-position: center;
}
#loading::before, #password-screen::before, #session-overlay::before, #error::before {
  background-image: url('promo_bg_1.png');
  animation: promoBgFlip 1s steps(1) infinite;
}
#loading::after, #password-screen::after, #session-overlay::after, #error::after {
  background-image: url('promo_bg_2.png');
  animation: promoBgFlip 1s steps(1) infinite reverse;
}
@keyframes promoBgFlip {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}

/* 背景圖上方約30%是活動banner美術（LOGO/文字），下方是留白紅色區塊，
   內容框改貼齊上方padding往下推，避免蓋住banner文字，水平方向仍要置中。
   #loading／#error是flex-direction:column（justify-content控制垂直），
   #password-screen／#session-overlay沒設flex-direction、預設是row
   （justify-content控制水平、align-items才是垂直）——兩種類型的容器要用
   不同屬性才能達到「垂直往下推、水平維持置中」，不能對四個選擇器套同一條
   規則（先前誤把row方向的justify-content:flex-start當成垂直用，結果變成
   序號輸入框被推到最左邊，是需要修正的錯誤） */
#loading,
#error {
  justify-content: flex-start !important;
  padding-top: 40dvh;
}
#password-screen,
#session-overlay {
  align-items: flex-start !important;
  justify-content: center !important;
  padding-top: 40dvh;
}

#loading {
  height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

/* 刮刮卡頁先套用AB主題的既有UI效果（.ip-space顯示＋卡片半透明白），促銷
   永遠只有這一種主題、不需要body.skin-ab條件判斷，直接套用即可。
   之後使用者會再指示IP素材細節如何呈現（例如.ip-space裡要放什麼圖） */
.ip-space {
  display: block;
  width: 100%;
  aspect-ratio: 5 / 1;
  flex-shrink: 0;
}
.card-page {
  background: rgba(255, 255, 255, 0.1);
}

/* 頂欄新增一排：貼左操作時間倒數／貼右剩餘次數 */
#promo-status-row {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  color: #fec804;
  font-weight: bold;
  padding-top: 4px;
}

/* 中獎/未中獎彈窗：雙按鈕（查看刮刮卡結果／刮下一張或確定） */
#modal-btns {
  display: flex;
  gap: 10px;
  margin-top: 6px;
}
#modal-reveal-btn,
#modal-next-btn {
  flex: 1;
  padding: 13px 6px;
  font-size: 14px;
  font-weight: bold;
  border: none;
  border-radius: 10px;
  cursor: pointer;
}
#modal-reveal-btn {
  background: #eee;
  color: #333;
}
#modal-reveal-btn:active { background: #ddd; }
#modal-next-btn {
  background: #0267b9;
  color: white;
}
#modal-next-btn:active { background: #0054a6; }

/* 查看結果後的收尾按鈕列（浮在格子區底部） */
#reveal-continue-bar {
  flex-shrink: 0;
  padding: 10px 14px calc(10px + env(safe-area-inset-bottom, 0px));
}
#reveal-continue-btn {
  width: 100%;
  padding: 14px;
  font-size: 16px;
  font-weight: bold;
  background: #0267b9;
  color: white;
  border: none;
  border-radius: 10px;
  cursor: pointer;
}
#reveal-continue-btn:active { background: #0054a6; }
