/* ==========================================================================
   小狼與小煎餅 — 版面樣式
   由 index.html 的 <style> 拆出來，內容原封不動。
   區塊索引：
     [CSS-1] 基礎與變數        [CSS-5] 話語卡（常駐）
     [CSS-2] 直式外框          [CSS-6] 下方操作鈕
     [CSS-3] 上方 HUD          [CSS-7] 覆蓋畫面（開始 / 勝 / 敗）
     [CSS-4] 舞台（畫布）
   ========================================================================== */

/* ==========================================================================
   [CSS-1] 基礎與變數
   ========================================================================== */
:root{
  --night-0:#120b1f;      /* 最深夜色 */
  --night-1:#1e1233;      /* 舞台底 */
  --night-2:#2c1c4a;      /* 舞台上緣 */
  --ink:#f3ecff;          /* 主要文字 */
  --ink-dim:#a795c4;      /* 次要文字 */
  --love:#ff6f9c;         /* 愛心粉 */
  --warm:#ffc46b;         /* 巧克力的暖光 */
  --calm:#8be0d4;         /* 話語青 */
  --bad:#5a2f7a;          /* 惡意泡泡 */
  --safe-b: env(safe-area-inset-bottom, 0px);
}
/* -webkit-touch-callout 是 iOS 專屬，而且非它不可：
   長按 <img> 跳出來的「儲存影像／拷貝」那張表單不是 contextmenu 事件，
   pointerdown 裡的 preventDefault() 和 contextmenu 監聽器都攔不到它，
   只有這個屬性關得掉。巧克力本來就要長按 1 秒，等於每次放大招都會踩到。 */
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;}
html,body{margin:0;height:100%;overflow:hidden;}
body{
  background:var(--night-0);
  color:var(--ink);
  font-family:"PingFang TC","Noto Sans TC","Hiragino Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
  user-select:none;-webkit-user-select:none;touch-action:manipulation;
  display:flex;justify-content:center;
}

/* ==========================================================================
   [CSS-2] 直式外框：手機滿版，桌機收成一條直式
   ========================================================================== */
#app{
  position:relative;width:100%;max-width:460px;height:100dvh;
  display:flex;flex-direction:column;
  background:linear-gradient(180deg,var(--night-2) 0%,var(--night-1) 45%,var(--night-0) 100%);
  overflow:hidden;
}

/* ==========================================================================
   [CSS-3] 上方 HUD：血條 / 分數 / 倒數 / 語言切換
   ========================================================================== */
#hud{padding:calc(env(safe-area-inset-top,0px) + 10px) 14px 8px;flex:0 0 auto;}
.hud-row{display:flex;align-items:center;gap:10px;}
.hud-stat{font-size:12px;color:var(--ink-dim);letter-spacing:.06em;}
.hud-val{font-size:18px;font-weight:700;font-variant-numeric:tabular-nums;color:var(--ink);}
#timeVal.urgent{color:var(--love);}
.spacer{flex:1;}
#langBtn{
  border:1px solid rgba(243,236,255,.28);background:rgba(243,236,255,.06);
  color:var(--ink);border-radius:999px;padding:6px 12px;font-size:12px;font-weight:600;
  /* 覆蓋層是 z-index:20，語言鈕要比它高，否則開始／勝利／失敗畫面一蓋上去就選不了語言 */
  position:relative;z-index:30;
}
/* 有覆蓋層時底色加重一點，才不會浮在暗畫面上看不清楚 */
#app.veiled #langBtn{
  background:rgba(243,236,255,.14);border-color:rgba(243,236,255,.45);
  box-shadow:0 6px 20px rgba(0,0,0,.45);
}
#hpTrack{
  margin-top:8px;height:12px;border-radius:999px;
  background:rgba(0,0,0,.35);border:1px solid rgba(243,236,255,.14);overflow:hidden;
}
#hpFill{
  height:100%;width:100%;border-radius:999px;
  background:linear-gradient(90deg,#ff8fb3,#ff5e8e);
  transition:width .22s ease;
}
#hpFill.low{background:linear-gradient(90deg,#ff7a5e,#e0344f);}

/* ==========================================================================
   [CSS-4] 舞台（畫布）
   ========================================================================== */
#stage{flex:1 1 auto;position:relative;min-height:0;transition:filter .5s ease;}
/* 血量低於 LOW_HP：整個舞台去飽和，世界看起來失去顏色 */
/* 只套在舞台、不套整個 #app，是為了讓上方血條維持紅色可讀 */
#stage.weak{filter:saturate(.22) brightness(.92);}
#game{position:absolute;inset:0;width:100%;height:100%;display:block;}
#stage.shake{animation:shake .22s ease;}
@keyframes shake{
  0%,100%{transform:translate(0,0);}
  25%{transform:translate(-5px,2px);}
  75%{transform:translate(5px,-2px);}
}
#hintLine{
  position:absolute;left:0;right:0;bottom:8px;text-align:center;
  font-size:11px;color:var(--ink-dim);opacity:.75;pointer-events:none;
}

/* ==========================================================================
   [CSS-5] 話語卡（常駐在畫面上，直接點就丟出去）
   ========================================================================== */
/* 常駐在畫面上，橫向捲動即可；不再有展開／收合 */
#cardWrap{flex:0 0 auto;position:relative;padding:8px 0 6px;}
#cardTray{
  display:flex;gap:8px;padding:0 12px;
  overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;
}
#cardTray::-webkit-scrollbar{display:none;}
/* 一局只發三張，讓它們平分寬度——這樣永遠不需要橫向捲動，
   三個選項一眼全看得到。min-width:0 是必要的：不加的話 flex 項目
   會以內容寬度為下限，長一點的英文句子就把版面撐爆了。 */
.card{
  flex:1 1 0;min-width:0;padding:11px 10px;
  /* 三張平分寬度之後，卡片變寬但字沒變大也還靠左，右邊就空一大塊。
     置中 + 放大字級是為了讓「留白」看起來是餘裕而不是沒填滿。
     用 flex 置中而不是 line-height：兩行的英文卡才會跟一行的中文卡等高對齊。 */
  display:flex;align-items:center;justify-content:center;
  min-height:44px;
  border-radius:13px;border:1px solid rgba(139,224,212,.45);
  background:linear-gradient(160deg,rgba(139,224,212,.16),rgba(139,224,212,.05));
  color:var(--calm);font-size:13.5px;line-height:1.4;text-align:center;
  letter-spacing:.02em;
  font-family:inherit;transition:opacity .18s ease;
}
.card:active{transform:scale(.96);}
/* 冷卻中：卡片變暗且不能點，下方細線顯示還要等多久 */
#cardTray.cooling .card{opacity:.32;}
.card:disabled{pointer-events:none;}
#wordCd{
  position:absolute;left:12px;right:12px;bottom:0;height:2px;border-radius:2px;
  background:rgba(139,224,212,.12);overflow:hidden;opacity:0;transition:opacity .2s ease;
}
#wordCd.on{opacity:1;}
#wordCd i{display:block;height:100%;width:0;background:var(--calm);}

/* ==========================================================================
   [CSS-6] 下方操作鈕（愛心 / 巧克力）
   ========================================================================== */
#controls{
  flex:0 0 auto;display:flex;gap:10px;
  padding:10px 12px calc(12px + var(--safe-b));
}
/* 圖左文右的橫排。原本是上下疊，圖和字擠在 76px 裡誰都不夠大；
   橫過來之後同樣的高度只放一行，圖可以放大、字也有呼吸的空間。
   高度維持 76px 不是排版需要，是觸控需要——巧克力要長按 1 秒，
   按鈕小一點手指就容易滑出去，那一秒就白按了。 */
.btn{
  position:relative;flex:1;height:76px;border-radius:20px;border:1px solid rgba(243,236,255,.16);
  background:rgba(243,236,255,.07);color:var(--ink);
  display:flex;flex-direction:row;align-items:center;justify-content:center;gap:10px;
  font-family:inherit;overflow:hidden;
}
.btn .ico{font-size:28px;line-height:1;flex:0 0 auto;}
.btn .lbl{font-size:14px;font-weight:600;letter-spacing:.03em;white-space:nowrap;}
.btn:active{transform:scale(.97);}
.btn[disabled]{opacity:.45;}
#btnHeart{border-color:rgba(255,111,156,.5);background:linear-gradient(180deg,rgba(255,111,156,.22),rgba(255,111,156,.06));}
#btnCheer{border-color:rgba(255,196,107,.5);background:linear-gradient(180deg,rgba(255,196,107,.2),rgba(255,196,107,.05));}
/* 冷卻遮罩：由下往上退去 */
.cool{
  position:absolute;left:0;right:0;bottom:0;height:0%;
  background:rgba(6,3,14,.68);pointer-events:none;
}
.cool-num{
  position:absolute;inset:0;display:none;align-items:center;justify-content:center;
  font-size:20px;font-weight:700;color:var(--ink);pointer-events:none;
}
.cool-num.show{display:flex;}
/* 巧克力的蓄力環 */
#chargeRing{
  position:absolute;inset:0;pointer-events:none;opacity:0;
  background:conic-gradient(var(--warm) calc(var(--p,0) * 1%),transparent 0);
  mix-blend-mode:screen;
}
#chargeRing.on{opacity:.5;}

/* ==========================================================================
   [CSS-7] 覆蓋畫面：開始 / 勝 / 敗
   ========================================================================== */
/* 覆蓋畫面會捲動。這不是為了好看，是為了不吃掉按鈕——
   換成繪師的圖之後，勝利畫面在 667px 高的手機上會超出約 70px，
   而原本是 justify-content:center 又沒有 overflow 設定，
   超出的部分會「上下兩端同時被裁掉」，「再玩一次」按鈕看不到也捲不到。

   做法：改成 flex-start + 頭尾各一個 margin:auto。
   內容短的時候 auto margin 會把它推到正中間（和原本一樣），
   內容長的時候 auto margin 收成 0、改由 overflow-y 接手，兩端都不會被切。 */
.overlay{
  position:absolute;inset:0;z-index:20;display:none;
  flex-direction:column;align-items:center;justify-content:flex-start;gap:14px;
  padding:32px 26px;text-align:center;
  background:rgba(10,5,20,.9);backdrop-filter:blur(6px);
  overflow-y:auto;overscroll-behavior:contain;
}
.overlay.show{display:flex;}
.overlay > :first-child{margin-top:auto;}
.overlay > :last-child{margin-bottom:auto;}
/* 沒有圖的時候（emoji 備援）維持原本的大小 */
.ov-art{font-size:64px;line-height:1;flex:0 0 auto;}
.ov-art .doll{font-size:38px;margin-left:-10px;vertical-align:-6px;}
/* 圖和標題是一組，靠近一點；和下面的說明才拉開 */
.ov-art.art{margin-bottom:-4px;}
.ov-title{font-size:24px;font-weight:800;letter-spacing:.02em;margin:0;}
.ov-text{font-size:15px;line-height:1.6;color:var(--ink-dim);margin:0;max-width:20em;}
.ov-stat{font-size:13px;color:var(--ink-dim);font-variant-numeric:tabular-nums;}
.ov-btn{
  margin-top:6px;padding:13px 30px;border-radius:999px;border:none;
  background:linear-gradient(90deg,var(--love),#ff9f6b);color:#2a0f1c;
  font-family:inherit;font-size:16px;font-weight:800;
}
.ov-btn:active{transform:scale(.97);}

/* ---- 開始畫面的音效開關 ----
   刻意做得比「開始陪牠」低調：它是個提醒，不是要跟主要動作搶注意力。
   但文字必須看得懂，因為它存在的唯一理由就是讓玩家知道「這裡會出聲」。 */
.ov-sound{
  margin-top:2px;padding:7px 15px;border-radius:999px;
  border:1px solid rgba(243,236,255,.28);background:rgba(243,236,255,.06);
  color:var(--ink-dim);font-family:inherit;font-size:12.5px;font-weight:600;
  display:inline-flex;align-items:center;gap:7px;letter-spacing:.02em;
}
.ov-sound:active{transform:scale(.97);}
/* 關閉時整顆再淡一階，和 HUD 那顆的表現一致 */
.ov-sound[aria-pressed="true"]{opacity:.5;}
/* 勝利畫面的按鈕先藏著，讓玩家有時間把信讀完（JS 三秒後移除 .pending）*/
.ov-btn.pending{opacity:0;transform:translateY(8px);pointer-events:none;}
.ov-btn{transition:opacity .6s ease,transform .6s ease;}

/* ---- 這局送出的話語，排成一封信 ---- */
.letter{
  width:100%;max-width:300px;text-align:left;
  padding:16px 18px 14px;border-radius:14px;
  background:linear-gradient(170deg,rgba(255,246,232,.96),rgba(248,235,215,.94));
  border:1px solid rgba(255,196,107,.5);
  box-shadow:0 16px 40px -18px rgba(0,0,0,.8);
  color:#4a3524;font-family:"Songti TC","Noto Serif TC",Georgia,serif;
}
.letter-head{font-size:14px;font-weight:700;margin-bottom:8px;}
.letter-body{
  font-size:13px;line-height:1.95;
  max-height:31vh;overflow-y:auto;-webkit-overflow-scrolling:touch;
}
.letter-body p{margin:0;text-indent:1em;}
.letter-body p::before{content:"「";}
.letter-body p::after{content:"」";}
.letter-body .empty{text-indent:0;color:#8a7358;font-style:italic;}
.letter-body .empty::before,.letter-body .empty::after{content:"";}
.letter-sign{margin-top:10px;font-size:12px;text-align:right;color:#7a6146;}
/* 失敗畫面比勝利畫面多一段文案，信要矮一點才塞得下小螢幕 */
#loseOv .letter-body{max-height:20vh;}
/* 勝利畫面多了輸入框，信紙本文也要讓位，否則小螢幕會被擠爆 */
#winOv .letter-body{max-height:18vh;}

/* ---- 信的最後一行：玩家自己寫的那句 ---- */
.compose{margin-top:12px;padding-top:12px;border-top:1px dashed rgba(122,97,70,.4);}
.compose[hidden]{display:none;}
.compose-lb{display:block;font-size:12px;color:#7a6146;margin-bottom:6px;}
.compose textarea,.compose input{
  width:100%;font-family:inherit;font-size:13px;line-height:1.6;color:#4a3524;
  background:rgba(255,255,255,.55);border:1px solid rgba(122,97,70,.35);
  border-radius:8px;padding:7px 9px;resize:none;
}
.compose textarea::placeholder,.compose input::placeholder{color:#a28b6d;}
.compose textarea:focus,.compose input:focus{outline:2px solid rgba(255,196,107,.7);outline-offset:1px;}
/* 剩餘字數：疊在輸入框右下角，快滿了才出現，平常不干擾 */
.compose-field{position:relative;}
.compose-left{
  position:absolute;right:8px;bottom:6px;pointer-events:none;
  font-size:11px;font-variant-numeric:tabular-nums;color:#a28b6d;
}
.compose-left.low{color:#a33b4a;font-weight:700;}
.compose-row{display:flex;gap:8px;margin-top:8px;}
.compose-row input{flex:1;min-width:0;}
.compose-send{
  flex:0 0 auto;padding:0 18px;border:none;border-radius:8px;
  background:linear-gradient(90deg,#c9704f,#d89a5a);color:#2a0f1c;
  font-family:inherit;font-size:13px;font-weight:800;
}
.compose-send:active{transform:scale(.97);}
.compose-send[disabled]{opacity:.5;}
/* 送出結果／錯誤訊息，成功和失敗共用同一行，靠 class 換顏色 */
.compose-msg{margin:8px 0 0;font-size:12px;line-height:1.6;color:#6b5a3f;min-height:0;}
.compose-msg.err{color:#a33b4a;}
.compose-msg a{color:#8a5a2a;}
#winOv .ov-title{color:var(--warm);}
#loseOv .ov-title{color:var(--love);}
/* 規則：原本是三條擠在一起的小字。改成三列，每列一個固定寬度的圖示格，
   圖示用的是遊戲裡真正會看到的東西（愛心圖、巧克力圖、話語卡色塊），
   不是 emoji——emoji 每個平台長得都不一樣，跟畫面上的美術也對不起來。 */
.rules{
  max-width:23em;text-align:left;padding:12px 14px;border-radius:12px;
  background:rgba(243,236,255,.05);border:1px solid rgba(243,236,255,.1);
  display:flex;flex-direction:column;gap:9px;
}
.rule{display:flex;gap:10px;align-items:flex-start;}
/* 固定寬度的圖示格：三列的文字才會對齊在同一條線上 */
.rule-ico{flex:0 0 26px;width:26px;display:flex;align-items:center;justify-content:center;}
.rule-ico.art{margin-top:1px;}
/* 話語卡沒有素材，畫一張和實際卡片同色的小卡代替 */
.rule-ico.chip{
  height:18px;margin-top:3px;border-radius:5px;
  border:1px solid rgba(139,224,212,.55);
  background:linear-gradient(160deg,rgba(139,224,212,.22),rgba(139,224,212,.06));
}
.rule-txt{font-size:12.5px;color:var(--ink-dim);line-height:1.6;}
.rule-txt b{color:var(--ink);font-weight:700;margin-right:.4em;}
.rule-win{
  margin:2px 0 0;padding-top:9px;font-size:12.5px;line-height:1.6;
  color:var(--ink);border-top:1px solid rgba(243,236,255,.1);
}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;}}

/* 蜜罐欄位。用「移出畫面」而不是 display:none，因為部分機器人會跳過
   display:none 的欄位——移出畫面它們仍然會填，我們才抓得到。 */
.vc-hp{
  position:absolute !important;left:-9999px !important;top:auto !important;
  width:1px !important;height:1px !important;opacity:0 !important;
  pointer-events:none !important;
}

/* 送出中的轉圈。用 currentColor 畫，所以套在任何按鈕上顏色都會自己對。
   減少動態偏好開啟時不轉，但環還在——文字已經寫著「送出中…」，
   靜止的環仍然是一個「有事情在進行」的訊號。 */
.sending::before{
  content:"";display:inline-block;
  width:.78em;height:.78em;margin-right:.45em;vertical-align:-.08em;
  border:2px solid currentColor;border-top-color:transparent;border-radius:50%;
  animation:vc-spin .7s linear infinite;
}
@keyframes vc-spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){
  .sending::before{animation:none;opacity:.6;}
}

/* ==========================================================================
   [CSS-8] 圖片裁切

   繪師的圖是 2048×2048、四周有大量留白，直接 <img> 放上去會出現一圈透明邊，
   而且不同狀態的留白比例不一樣，排版會忽大忽小。

   用一個 overflow:hidden 的框把圖裁到內容範圍：
     --sx / --sy  裁切框左上角在原圖上的座標
     --sw / --sh  裁切框的尺寸
     --w          最後要顯示多寬
   其餘尺寸由 calc 算出來。換圖時只要量出新的內容邊界、改這四個數字就好。
   ========================================================================== */
.art{
  position:relative;overflow:hidden;display:inline-block;line-height:0;
  width:var(--w);
  height:calc(var(--w) * var(--sh) / var(--sw));
}
.art img{
  position:absolute;display:block;
  /* 第二道防線，補 iOS 以外的平台：
     pointer-events:none 讓觸控完全落不到圖上（.art 在站上一律是裝飾，
     真正該收到事件的是外層按鈕），Android Chrome 和桌機的長按／拖曳
     就沒有對象可以彈出選單或起拖。user-drag 再擋掉滑鼠把圖拖走。 */
  pointer-events:none;-webkit-user-drag:none;user-select:none;-webkit-user-select:none;
  width:calc(var(--w) * 2048 / var(--sw));
  height:auto;
  left:calc(var(--w) * var(--sx) / var(--sw) * -1);
  top:calc(var(--w) * var(--sy) / var(--sw) * -1);
}
/* 覆蓋畫面的圖：.ov-art 原本是 64px 的 emoji，改成圖片後尺寸由 --w 決定 */
.ov-art.art{font-size:0;}

/* ==========================================================================
   [CSS-9] 開始畫面的小狼待機動作

   靜態 PNG 動不了尾巴或眼睛（那些畫在圖裡），但整隻的姿態可以動。
   三個一起做才會像活的：呼吸（縱向縮放）、浮動（上下）、搖晃（左右傾）。

   ⚠ 只能動外框，不能動裡面的 <img>。
     .art 是 overflow:hidden 的裁切窗、img 是絕對定位的底圖——
     動 img 的話小狼會在窗口裡滑動並被裁掉半邊。動外框才是整隻一起動。

   ★ 四個旋鈕都在下面，想調快慢或幅度改這四個就好 ★
   ========================================================================== */
#startOv .ov-art.art{
  --idle-dur:    3.4s;    /* 一個循環多久。調大＝更慢更沉穩 */
  --idle-lift:   5px;     /* 上下浮動的幅度 */
  --idle-tilt:   1.6deg;  /* 左右搖晃的角度 */
  --idle-breath: 0.022;   /* 呼吸的縮放幅度（0.02 約等於 2%）*/

  /* 軸心放在腳的位置：呼吸和搖晃要以「站著的地方」為支點，
     用預設的正中心會變成整隻在空中扭動，看起來像被吊著。 */
  transform-origin: 50% 94%;
  animation: wolf-idle var(--idle-dur) ease-in-out infinite;
  /* 動畫期間會反覆重繪，先提示瀏覽器交給合成層處理 */
  will-change: transform;
}

@keyframes wolf-idle{
  /* 四個關鍵格：吸氣 → 呼氣 → 吸氣 → 回到原位，
     左右各傾一次，所以搖晃的週期是呼吸的一半，看起來不會太規律 */
  0%, 100%{
    transform: translateY(0)
               scale(1, 1)
               rotate(0deg);
  }
  25%{
    transform: translateY(calc(var(--idle-lift) * -1))
               scale(calc(1 - var(--idle-breath)), calc(1 + var(--idle-breath)))
               rotate(calc(var(--idle-tilt) * -1));
  }
  50%{
    transform: translateY(calc(var(--idle-lift) * -0.25))
               scale(calc(1 + var(--idle-breath) * 0.6), calc(1 - var(--idle-breath) * 0.4))
               rotate(0deg);
  }
  75%{
    transform: translateY(calc(var(--idle-lift) * -1))
               scale(calc(1 - var(--idle-breath)), calc(1 + var(--idle-breath)))
               rotate(var(--idle-tilt));
  }
}

/* 有開「減少動態」偏好的人就完全靜止。
   全站的 reduced-motion 規則寫在上面（*{animation:none!important}），
   這裡不必重複，留這段註解是為了讓人知道已經照顧到了。 */

/* ---- 音樂開關 ---- */
#musicBtn{
  border:1px solid rgba(243,236,255,.28);background:rgba(243,236,255,.06);
  color:var(--ink);border-radius:999px;
  width:32px;height:28px;padding:0;font-size:13px;line-height:1;
  font-family:inherit;
  /* 和語言鈕一樣要浮在覆蓋層之上，否則開始畫面一蓋上去就按不到 */
  position:relative;z-index:30;
}
#app.veiled #musicBtn{
  background:rgba(243,236,255,.14);border-color:rgba(243,236,255,.45);
  box-shadow:0 6px 20px rgba(0,0,0,.45);
}
/* 靜音時整顆變暗，一眼看得出狀態 */
#musicBtn[aria-pressed="true"]{opacity:.45;}


/* 覆蓋層上的「回站上」連結。
   這一頁自成一格、沒有站台的導覽列，進導覽列之後從搜尋或分享連結進來的人
   會走進死路（只能按上一頁）。所以三個覆蓋層各放一條回去的路。
   刻意不放在 HUD：那排在遊戲進行中一直都在，手機誤觸就是直接離開、進度全沒。 */
.ov-back{
  margin-top:14px;font-size:13px;letter-spacing:.04em;
  color:var(--ink-dim);text-decoration:none;
  border-bottom:1px solid rgba(243,236,255,.22);padding-bottom:2px;
}
.ov-back:hover{color:var(--ink);border-bottom-color:rgba(243,236,255,.5);}
