        @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;500;700;900&family=Zen+Kaku+Gothic+New:wght@700;900&display=swap');

        /* v42：移除了 html.in-iframe 相關的一整組樣式（Google Sites iframe
           內的版面修正），因為對應的 JS 偵測/加上這個 class 的邏輯，早在
           先前清理 Google Sites 相容性代碼那一輪就已經移除，這幾條規則
           從那之後就沒有任何元素會用到，屬於殘留樣式。 */




        /* 裝飾符號 fallback */
        .deco-star {
            font-family: 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Emoji', sans-serif;
            font-style: normal;
        }

        /* flag-icons 在語言選單內的尺寸 */
        .fi {
            width: 1.33em;
            line-height: 1em;
            border-radius: 2px;
            vertical-align: -0.1em;
            display: inline-block;
        }
        /* 頁面切換淡入
           注意：.page-content 的實際淡入動畫定義在後面（fadeIn，約行 481），
           這裡原本有第二份重複定義（pageFadeIn），因為 CSS 選擇器優先度
           相同、後者覆蓋前者，前者從未真正生效過，屬於死碼，已移除，
           避免以後誤以為改了這裡動畫就會生效。 */

        /* ── GIF 安全隱藏：page-portfolio 永不用 display:none ──
           display:none 會讓瀏覽器釋放 GIF 解碼狀態，切回來必定閃爍重置。
           改用 position:absolute + visibility:hidden，GIF 保持在渲染樹中不間斷播放。 */
        #page-portfolio {
            animation: none !important;  /* 禁止任何 opacity 動畫 */
        }
        /* 作品展示頁：子元素的緩入+上移動畫（只用 transform，不動 opacity，不影響 GIF）*/
        #page-portfolio .port-reveal {
            opacity: 0;
            transform: translateY(24px);
            transition: opacity 0.5s cubic-bezier(0.4,0,0.2,1), transform 0.5s cubic-bezier(0.4,0,0.2,1);
        }
        #page-portfolio .port-reveal.visible {
            opacity: 1;
            transform: translateY(0);
        }
        #page-portfolio.gif-hidden {
            /* ── v31 根治閃爍：移出可視區但保留在 Render Tree，GIF 持續解碼不中斷 ── */
            position: fixed !important;
            top: 0 !important;
            left: 0 !important;
            /* transform 移到螢幕外並建立獨立 GPU compositing layer */
            transform: translate3d(-9999px, 0, 0) !important;
            -webkit-transform: translate3d(-9999px, 0, 0) !important;
            opacity: 0 !important;
            visibility: hidden !important;
            pointer-events: none !important;
            overflow: hidden !important;
            /* 保留正常寬度，讓 Chromium 持續解碼 GIF（width:0 會讓瀏覽器暫停解碼） */
            width: 100vw !important;
            height: 100vh !important;
            /* 阻絕任何外層 repaint 污染 GIF 解碼狀態 */
            isolation: isolate !important;
            will-change: transform !important;
        }

        .material-symbols-outlined {
            font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
            font-size: 1.1em;
            line-height: 1;
            vertical-align: -0.15em;
            display: inline-block;
            user-select: none;
        }

        :root {
            --bg-primary: #06030f;
            --accent-primary: #a855f7;
            --accent-secondary: #ec4899;
            --accent-glow: rgba(168, 85, 247, 0.45);
            --glass-border: rgba(255, 255, 255, 0.07);
            --text-main: #e9d5ff;
            --panel-bg: rgba(18, 8, 36, 0.75);
        }

        /* 白天模式 — v53 重新設計：拉大「頁面背景」跟「卡片表面」的對比
           之前頁面背景（#d8d0e8）跟卡片背景（rgba(220,210,240,0.90)）幾乎
           是同一個亮度層級的淺紫色，卡片自然「浮不出來」；邊框顏色
           （rgba(100,60,150,0.25)）疊在同樣偏淺的背景上，混合後跟背景幾乎
           融為一體，難怪邊框像是消失了。
           重新設計原則：頁面背景維持中等飽和度的薰衣草紫（不要太淺，
           不然卡片跟輸入框這些「介面表面」很難跟它拉開層次）；所有卡片／
           表面元件（glass-panel、nav、輸入框、下拉選單、option-card）統一
           改成接近純白、更不透明的色調，形成清楚的「頁面背景 vs. 介面表面」
           兩個明確層次；邊框則整批換成更飽和、透明度更高的紫色
           （rgba(107,33,168, 0.4~0.5)），不管疊在頁面背景還是卡片表面上
           都清楚可辨。 */
        body.light-mode {
            --bg-primary: #c7bce0;
            --text-main: #1a1030;
            --panel-bg: rgba(250, 247, 255, 0.95);
            --glass-border: rgba(107, 33, 168, 0.45);
            background-image: 
                radial-gradient(circle at 15% 50%, rgba(140, 90, 200, 0.20), transparent 30%),
                radial-gradient(circle at 85% 30%, rgba(80, 100, 200, 0.16), transparent 30%),
                radial-gradient(circle at 50% 90%, rgba(180, 120, 80, 0.12), transparent 30%);
        }
        body.light-mode .text-white { color: #1a1030 !important; }
        body.light-mode .text-gray-300, body.light-mode .text-purple-200 { color: #4a3060 !important; }
        body.light-mode .text-purple-300 { color: #6b21a8 !important; }
        body.light-mode .text-purple-400 { color: #5b1898 !important; }
        body.light-mode .text-gray-400 { color: #5a4c72 !important; }
        body.light-mode .bg-black\/40, body.light-mode .bg-black\/50, body.light-mode .bg-black\/30, body.light-mode .bg-black\/20 { 
            background-color: rgba(248, 244, 253, 0.88) !important; 
            color: #1a1030 !important;
            border-color: rgba(107, 33, 168, 0.4) !important;
        }
        body.light-mode .option-card { background: rgba(248, 244, 253, 0.90); }
        body.light-mode .text-gradient { background: linear-gradient(to right, #7b11b8, #d4389a); -webkit-background-clip: text; }
        body.light-mode .border-white\/5, body.light-mode .border-white\/10 { border-color: rgba(107, 33, 168, 0.38) !important; }
        body.light-mode input, body.light-mode textarea, body.light-mode select { 
            color: #1a1030 !important; 
            background-color: rgba(248, 244, 255, 0.72) !important;
            border-color: rgba(107, 33, 168, 0.42) !important;
        }
        body.light-mode .glass-panel {
            background: rgba(250, 247, 255, 0.94);
            border-color: rgba(107, 33, 168, 0.4);
            box-shadow: 0 4px 24px rgba(80, 40, 140, 0.18);
        }
        body.light-mode nav { background: rgba(248, 244, 255, 0.92) !important; border-color: rgba(107, 33, 168, 0.35) !important; }
        body.light-mode .tab-btn { color: #6b21a8 !important; }
        body.light-mode .tab-btn.active { color: #1a1030 !important; }
        body.light-mode header p { color: #6b21a8 !important; }
        body.light-mode #langMenu { background: rgba(250, 247, 255, 0.99) !important; border-color: rgba(107, 33, 168, 0.4) !important; }
        body.light-mode #langMenu button { color: #3b1f6e !important; }
        body.light-mode #langMenu button:hover { background: rgba(130, 80, 190, 0.15) !important; color: #1a1030 !important; }
        body.light-mode .text-emerald-400 { color: #065f46 !important; }
        body.light-mode .text-blue-300 { color: #1e3a8a !important; }
        body.light-mode .text-yellow-300 { color: #92400e !important; }
        body.light-mode .text-red-400 { color: #991b1b !important; }
        body.light-mode ::-webkit-scrollbar-track { background: #c7bce0; }

        /* v54 修復：core.html 方案選擇卡片的懸浮提示框（.plan-tooltip）
           本身固定是黑色背景＋backdrop-blur（不管深色/淺色模式都一樣，
           刻意設計成永遠是深色浮層，方便疊在任何顏色的卡片上都能維持
           閱讀性，類似原生系統 tooltip 的做法）。但淺色模式的文字覆寫
           規則是全站套用的，會把提示框裡的文字也一起強制變成深色，
           結果就是「深色文字疊在黑色背景上」幾乎看不見，等於文字被
           蓋住了。這裡把提示框內的文字顏色鎖定回原本設計的淺色系，
           不受淺色模式覆寫影響。 */
        body.light-mode .plan-tooltip { color: #e9d5ff !important; }
        body.light-mode .plan-tooltip .text-blue-300 { color: #93c5fd !important; }
        body.light-mode .plan-tooltip .text-blue-400 { color: #60a5fa !important; }
        body.light-mode .plan-tooltip .text-emerald-400 { color: #34d399 !important; }
        body.light-mode .plan-tooltip .text-purple-200\/70 { color: rgba(233,213,255,0.7) !important; }
        body.light-mode .plan-tooltip .text-purple-200\/80 { color: rgba(233,213,255,0.8) !important; }
        body.light-mode .plan-tooltip .text-purple-400 { color: #c084fc !important; }
        body.light-mode .plan-tooltip .text-purple-400\/50 { color: rgba(192,132,252,0.5) !important; }
        body.light-mode .plan-tooltip .text-yellow-300 { color: #fde047 !important; }
        body.light-mode .plan-tooltip .text-yellow-300\/70 { color: rgba(253,224,71,0.7) !important; }
        body.light-mode .plan-tooltip .text-yellow-400 { color: #facc15 !important; }

        /* 白天模式追加修復：所有可能偏淺的文字 */
        body.light-mode .text-purple-200\/80 { color: #4a3060 !important; }
        body.light-mode .text-purple-200\/70 { color: #5a4070 !important; }
        body.light-mode .text-purple-300\/70 { color: #6b21a8 !important; }
        body.light-mode .text-purple-300\/60 { color: #7c3aad !important; }
        body.light-mode .text-white\/80 { color: #2a1a40 !important; }
        body.light-mode .text-gray-200 { color: #2a1a40 !important; }
        body.light-mode .text-gray-100 { color: #1a1030 !important; }
        /* 服務卡片內小字 */
        body.light-mode .text-gray-400 { color: #4a3a60 !important; }
        /* 所有 bg-black/* 內的文字強制深色 */
        body.light-mode [class*="bg-black"] { color: #1a1030 !important; }
        body.light-mode [class*="bg-black"] span,
        body.light-mode [class*="bg-black"] p,
        body.light-mode [class*="bg-black"] label,
        body.light-mode [class*="bg-black"] div { color: #1a1030 !important; }
        /* 保留綠色/藍色/紅色語義色 */
        body.light-mode [class*="bg-black"] .text-emerald-400 { color: #065f46 !important; }
        body.light-mode [class*="bg-black"] .text-blue-400 { color: #1e40af !important; }
        body.light-mode [class*="bg-black"] .text-red-400 { color: #991b1b !important; }
        body.light-mode [class*="bg-black"] .text-yellow-300 { color: #92400e !important; }
        body.light-mode [class*="bg-black"] .text-pink-400 { color: #9d174d !important; }
        body.light-mode [class*="bg-black"] .text-purple-400,
        body.light-mode [class*="bg-black"] .text-purple-300,
        body.light-mode [class*="bg-black"] .text-purple-200 { color: #6b21a8 !important; }
        /* option card 選項卡文字 */
        body.light-mode .option-card * { color: #1a1030 !important; }
        body.light-mode .option-card .text-emerald-400 { color: #065f46 !important; }
        /* glass-panel 內文字 */
        body.light-mode .glass-panel p,
        body.light-mode .glass-panel span,
        body.light-mode .glass-panel label,
        body.light-mode .glass-panel li { color: #2a1a44 !important; }
        body.light-mode .glass-panel strong,
        body.light-mode .glass-panel h3,
        body.light-mode .glass-panel h4 { color: #1a1030 !important; }
        /* 明細清單 */
        body.light-mode #detailList div,
        body.light-mode #animDetailList div { color: #1a1030 !important; border-color: rgba(107,33,168,0.35) !important; }
        /* code 標籤 */
        body.light-mode code { background: rgba(107,33,168,0.18) !important; color: #5b1898 !important; }
        /* 連結 */
        body.light-mode a.text-blue-400 { color: #1e40af !important; }
        /* nav 上的 tab 按鈕 active 狀態 */
        body.light-mode .tab-btn.active { background: rgba(107,33,168,0.28) !important; color: #1a1030 !important; }
        /* 明確加深 service icon */
        body.light-mode .service-icon { background: rgba(107,33,168,0.22) !important; color: #5b1898 !important; }
        /* 開關說明文字 */
        body.light-mode .text-xs { color: #3a2855 !important; }
        body.light-mode .text-sm { color: #2a1a44 !important; }

        body {
            font-family: 'Noto Sans TC', sans-serif;
            background-color: var(--bg-primary);
            background-image: 
                radial-gradient(ellipse at 10% 20%, rgba(168, 85, 247, 0.12), transparent 40%),
                radial-gradient(ellipse at 90% 10%, rgba(236, 72, 153, 0.08), transparent 35%),
                radial-gradient(ellipse at 50% 80%, rgba(59, 130, 246, 0.07), transparent 40%);
            background-attachment: fixed;
            color: var(--text-main);
            /* v44 修復：上一版這裡試過 overflow-x: clip（搭配 overflow-y: visible），
               理論上 clip 不應該讓 body 變成捲動容器，但這個屬性在不同瀏覽器的
               實際行為還是有模糊地帶，實測下來 .sticky-summary 的浮動效果依然
               沒有正確運作。這裡改成最直接、最不會有疑慮的做法：body 完全不
               設定 overflow（維持瀏覽器預設的 visible），這是唯一「保證」不會
               讓瀏覽器把 body 當成捲動容器、進而影響子元素 position:sticky 的
               做法。原本想避免的水平捲軸問題，目前檢查過網站上會造成水平溢出
               的裝飾元素（流星背景 canvas 是 fixed 定位、背景漸層是
               background-image，兩者都不會產生可捲動的溢出範圍），實際上不需要
               靠 body 層級的 overflow 限制來預防。如果之後真的發現有特定元素
               造成水平捲軸，應該直接修那個元素本身（例如幫它加
               max-width:100vw 或 overflow:hidden），而不是在 body 這種高層級
               的祖先元素上動手，才不會又牽連到 sticky 定位。 */
            transition: background-color 0.5s ease, color 0.5s ease;

        }

        ::-webkit-scrollbar { width: 8px; }
        ::-webkit-scrollbar-track { background: var(--bg-primary); }
        ::-webkit-scrollbar-thumb { background: #6b21a8; border-radius: 4px; }
        ::-webkit-scrollbar-thumb:hover { background: #a78bfa; }

        .glass-panel {
            background: var(--panel-bg);
            backdrop-filter: blur(16px);
            -webkit-backdrop-filter: blur(16px);
            border: 1px solid var(--glass-border);
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255,255,255,0.05);
            border-radius: 1.5rem;
            /* 只 transition 需要的屬性，避免 backdrop-filter/box-shadow 被納入 transition 範圍 */
            transition: border-color 0.4s ease, box-shadow 0.4s ease;
            /* contain removed: caused GIF flicker and blocked cross-panel repaint batching */
        }

        /* ── GIF 輪播卡：移除 backdrop-filter，防止 Google Sites iframe 中
              backdrop-filter 產生新 compositing layer 導致 GIF 幀重置閃爍 ── */
        .carousel-card {
            backdrop-filter: none !important;
            -webkit-backdrop-filter: none !important;
            background: rgba(10, 5, 25, 0.88) !important;
            /* isolation: isolate 建立獨立 stacking context，
               防止外層 opacity/transform repaint 污染 GIF 解碼狀態 */
            isolation: isolate;
            /* v31：強制建立獨立 GPU compositing layer，切換頁籤/主題時不波及 GIF 解碼 */
            will-change: transform;
            transform: translate3d(0, 0, 0);
            -webkit-transform: translate3d(0, 0, 0);
            backface-visibility: hidden;
            -webkit-backface-visibility: hidden;
        }
        /* GIF img 提升至獨立 GPU compositing layer，
           防止 canvas/scroll repaint 導致 GIF 幀重置 */
        /* ── v29 行動端防盜：carousel-img + ulbImg + portfolio 所有作品圖 ──
           完整跨瀏覽器防長按存圖保護（iOS / Android / 桌面）
           pointer-events: auto 保留點擊燈箱功能，僅限制長按儲存行為 */
        .carousel-img, #ulbImg,
        #page-portfolio img,
        #gif-grid-stickers img,
        #gif-grid-logos img {
            will-change: transform;
            transform: translate3d(0, 0, 0);
            -webkit-transform: translate3d(0, 0, 0);
            backface-visibility: hidden;
            -webkit-backface-visibility: hidden;
            /* 防盜：禁用長按彈出「儲存圖片」選單 */
            -webkit-touch-callout: none;
            /* 禁用文字/圖片選取（所有瀏覽器前綴） */
            -webkit-user-select: none;
            -khtml-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
            /* 保留點擊燈箱，僅限制長按儲存 */
            pointer-events: auto;
        }

        /* ── v29 一鍵複製委託清單按鈕樣式 ── */
        .btn-copy-summary {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 0.5rem;
            width: 100%;
            padding: 0.75rem 1rem;
            border-radius: 0.875rem;
            font-weight: 700;
            font-size: 0.875rem;
            color: #e9d5ff;
            background: linear-gradient(135deg, rgba(139,92,246,0.18) 0%, rgba(236,72,153,0.12) 100%);
            border: 1px solid rgba(139,92,246,0.35);
            cursor: pointer;
            transition: background 0.2s, border-color 0.2s, transform 0.15s, box-shadow 0.2s;
            position: relative;
            overflow: hidden;
        }
        .btn-copy-summary::before {
            content: '';
            position: absolute;
            inset: 0;
            background: linear-gradient(120deg, transparent 30%, rgba(168,85,247,0.18) 50%, transparent 70%);
            transform: translateX(-120%);
            pointer-events: none;
            transition: none;
        }
        .btn-copy-summary:hover::before { transform: translateX(120%); transition: transform 0.5s ease; }
        .btn-copy-summary:hover {
            background: linear-gradient(135deg, rgba(139,92,246,0.30) 0%, rgba(236,72,153,0.20) 100%);
            border-color: rgba(168,85,247,0.55);
            box-shadow: 0 0 20px rgba(168,85,247,0.20);
            transform: translateY(-1px);
        }
        .btn-copy-summary:active { transform: translateY(0) scale(0.98); }
        .btn-copy-summary.copied {
            background: linear-gradient(135deg, rgba(52,211,153,0.22) 0%, rgba(16,185,129,0.14) 100%);
            border-color: rgba(52,211,153,0.50);
            color: #34d399;
        }
        body.light-mode .btn-copy-summary { color: #3b1f6e; border-color: rgba(100,60,150,0.35); background: rgba(200,185,240,0.40); }

        /* ── v29 規範錨點連結樣式 ── */
        .anchor-rules-link {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 0.375rem;
            font-size: 0.72rem;
            font-weight: 700;
            color: rgba(192,132,252,0.65);
            cursor: pointer;
            padding: 0.4rem 0.6rem;
            border-radius: 0.5rem;
            transition: color 0.2s, background 0.2s;
            text-decoration: none;
            letter-spacing: 0.02em;
            background: transparent;
            border: none;
        }
        .anchor-rules-link:hover { color: #e9d5ff; background: rgba(139,92,246,0.10); }
        body.light-mode .anchor-rules-link { color: #6b21a8; }
        body.light-mode .anchor-rules-link:hover { color: #1a1030; background: rgba(100,60,150,0.10); }
        /* 包裹 GIF 的容器同樣建立獨立 layer */
        .carousel-img-wrap {
            transform: translate3d(0, 0, 0);
            -webkit-transform: translate3d(0, 0, 0);
            isolation: isolate;
            backface-visibility: hidden;
            -webkit-backface-visibility: hidden;
        }

        .glass-panel:hover {
            border-color: rgba(168, 85, 247, 0.2);
            box-shadow: 0 12px 40px rgba(0,0,0,0.25), inset 0 1px 0 rgba(255,255,255,0.07);
        }
        /* 有左色條的 section：預設透明，hover 才顯示 */
        .glass-panel.border-l-4 {
            border-left-color: transparent !important;
            transition: border-left-color 0.3s ease, box-shadow 0.4s ease, border-color 0.4s ease;
        }
        .glass-panel.border-l-blue-500:hover   { border-left-color: rgb(59 130 246) !important; }
        .glass-panel.border-l-purple-500:hover { border-left-color: rgb(168 85 247) !important; }
        .glass-panel.border-l-emerald-500:hover { border-left-color: rgb(16 185 129) !important; }

        /* 報價單頂部色條：預設透明，hover 才顯示 */
        .glass-panel.border-t-4 {
            border-top-color: transparent !important;
            transition: border-top-color 0.3s ease, box-shadow 0.4s ease, border-color 0.4s ease;
        }
        .glass-panel.border-t-purple-500:hover { border-top-color: rgb(168 85 247) !important; }

        .text-gradient {
            background: linear-gradient(135deg, #e879f9 0%, #a855f7 40%, #818cf8 80%, #67e8f9 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
            /* hue-rotate 在 compositor thread 執行，不觸發 main thread paint */
            animation: gradient-shift 6s linear infinite;
        }

        @keyframes gradient-shift {
            0%   { filter: hue-rotate(0deg); }
            100% { filter: hue-rotate(30deg); }
        }

        /* ── Scroll Reveal ── */
        .reveal {
            opacity: 0;
            transform: translateY(16px) scale(0.98);
            transition: opacity 0.35s cubic-bezier(0.4,0,0.2,1), transform 0.35s cubic-bezier(0.4,0,0.2,1);
        }
        .reveal.visible {
            opacity: 1;
            transform: translateY(0) scale(1);
        }

        /* ── 預估總金額：緩緩浮現的入場動畫（修復問題4）──
           搭配 common.js 的 revealAmountOnLoad()，在 core.html／anim.html／
           template.html 的計算機第一次算出金額時套用，取代原本「文字瞬間
           出現」的顯示方式。 */
        .amount-enter {
            animation: amount-enter-fade 0.6s cubic-bezier(0.4,0,0.2,1);
        }
        @keyframes amount-enter-fade {
            from { opacity: 0; transform: translateY(8px); }
            to   { opacity: 1; transform: translateY(0); }
        }

        /* ── 預估總金額：數字變動時的「閃光脈衝」提示（修復問題4）──
           搭配 common.js 的 flashAmount()，每次金額因為使用者互動而改變、
           滾動數字動畫播放時，附加這個短暫的發光＋縮放脈衝，讓「金額變了」
           這件事更容易被使用者注意到。 */
        .amount-flash {
            animation: amount-flash-pulse 0.6s ease-out;
        }
        @keyframes amount-flash-pulse {
            0%   { text-shadow: 0 0 0px rgba(217,70,239,0); }
            35%  { text-shadow: 0 0 16px rgba(217,70,239,0.85), 0 0 32px rgba(139,92,246,0.5); }
            100% { text-shadow: 0 0 0px rgba(217,70,239,0); }
        }
        /* v50：template.html 的面板邊框是 fuchsia（桃紅）色系而不是 core／anim
           那種 purple 色系，脈衝顏色跟著換一組桃紅色調，呼應各頁自己的主題色，
           不會讓三頁看起來像同一份模板套上去而已。 */
        .amount-flash-fuchsia {
            animation: amount-flash-pulse-fuchsia 0.6s ease-out;
        }
        @keyframes amount-flash-pulse-fuchsia {
            0%   { text-shadow: 0 0 0px rgba(232,121,249,0); }
            35%  { text-shadow: 0 0 16px rgba(232,121,249,0.9), 0 0 32px rgba(217,70,239,0.55); }
            100% { text-shadow: 0 0 0px rgba(232,121,249,0); }
        }

        /* ── 預估總金額：算出來之前的骨架屏（v50 新增）──
           core.html／anim.html／template.html 三頁的計算機腳本要等
           common.js＋各自的 xxx-render.js 這幾支外部檔案載入、執行完才會
           算出第一次金額；連線比較慢的時候，使用者會先看到寫死在 HTML
           裡的「NT$ ···」純文字幾百毫秒到幾秒不等。改成套用同一套
           GIF 卡片骨架屏用的 shimmer 動畫，數字算出來的當下（見 common.js
           的 revealAmountOnLoad() ／ template-render.js 的 tmplCalculate()）
           會立刻拿掉這個 class，換回真正的金額文字。 */
        .price-skeleton {
            position: relative;
            display: inline-block;
            color: transparent !important;
            min-width: 6.5em;
            min-height: 1em;
            border-radius: 0.5rem;
            background: linear-gradient(
                90deg,
                rgba(255,255,255,0.05) 0%,
                rgba(255,255,255,0.14) 40%,
                rgba(255,255,255,0.05) 80%
            );
            background-size: 200% 100%;
            animation: skeleton-shimmer 1.6s ease-in-out infinite;
        }
        /* v53：白色系 shimmer 是為深色背景設計的，疊在淺色模式的淺色卡片上
           幾乎看不見，改用深紫色系漸層維持一樣的可見度。 */
        body.light-mode .price-skeleton {
            background: linear-gradient(
                90deg,
                rgba(107,33,168,0.10) 0%,
                rgba(107,33,168,0.24) 40%,
                rgba(107,33,168,0.10) 80%
            );
            background-size: 200% 100%;
        }

        /* ── 卡片 hover 微浮起效果（v50 新增，v51 修正衝突）──
           之前所有 .glass-panel 只有「捲動進入視窗時」的淡入動畫，滑鼠移
           上去卻完全沒有回饋。只在支援真正 hover 的裝置上啟用（觸控裝置
           沒有懸停這件事，用 (hover: hover) 排除掉手機/平板，避免觸控後
           出現「卡住的 hover 狀態」）。效果刻意做得很輕，就算套用在大面積
           的容器上也不會顯得誇張。
           v51 修正：合作繪師卡片（hover:-translate-y-2）、首頁特色卡片
           （hover:scale-105）、二創卡片（hover:scale-[1.02]）這些元素
           本來就已經用 Tailwind 的 hover 工具 class 自己做了 transform
           效果，跟這裡的規則同時套用在同一個 transform 屬性上會互相打架、
           結果不穩定（取決於 Tailwind 產生的樣式表跟這份 common.css 誰
           後載入）。用 [class*="hover:scale"] / [class*="hover:-translate"]
           屬性選擇器排除掉這些「已經有自己 hover 效果」的元素，只補強
           真的什麼互動回饋都沒有的卡片。 */
        @media (hover: hover) and (pointer: fine) {
            .glass-panel:not([class*="hover:scale"]):not([class*="hover:-translate"]) {
                transition: transform 0.25s ease, box-shadow 0.25s ease;
            }
            .glass-panel:not([class*="hover:scale"]):not([class*="hover:-translate"]):hover {
                transform: translateY(-3px);
                box-shadow: 0 14px 28px -12px rgba(139,92,246,0.35);
            }
        }

        /* ── 手機不需要浮動報價提示條（v50）──
           #floatingQuoteBar 原本是給桌機用、捲動超過報價區時才浮現的
           小提示條；但手機螢幕已經夠窄了，再疊一個 fixed 定位的浮動視窗
           在畫面下方，反而容易跟其他固定元素（如導覽列、回頂部按鈕）
           互相干擾、擠壓內容空間。跟桌機用 initScrollFollowPanel() 的
           lg（1024px）門檻保持一致，小於這個寬度就直接不顯示，手機版
           維持原本「往下捲就看得到報價區」的單純捲動方式即可。 */
        @media (max-width: 1023px) {
            #floatingQuoteBar {
                display: none !important;
            }
        }

        /* ── 深色/淺色模式切換過渡（v52 新增）──
           搭配 common.js 的 toggleTheme()：切換的短暫期間內，讓所有元素
           的顏色/背景/邊框變化都平滑過渡，而不是瞬間跳色。用 !important
           蓋過各元素原本（若有）不同速度的 transition 設定，確保這段
           期間內全部用同一個速度變化，避免顏色更新速度不一致、看起來
           參差不齊。只在切換當下短暫套用，過渡結束後就會移除，不會
           影響其他地方（如卡片 hover）原本的過渡速度。 */
        body.theme-transition,
        body.theme-transition * {
            transition: background-color 0.55s ease, color 0.55s ease,
                        border-color 0.55s ease, box-shadow 0.55s ease !important;
        }

        /* ── 語言切換過渡（v52 新增）──
           搭配 common.js 的 setLang()：換語言時，上百個 [data-i18n] 元素
           的文字會在同一瞬間全部替換掉，文字內容本身沒辦法用 transition
           做動畫。改成讓整個頁面在替換文字的那一刻極短暫地變暗，把生硬
           的瞬間切換包裝成一次平滑的過渡，而不是單純的「消失又出現」。 */
        body {
            transition: opacity 0.28s ease;
        }
        body.lang-switching {
            opacity: 0.55;
        }

        /* ── Back to top ── */
        #backToTop {
            position: fixed;
            bottom: 2rem;
            right: 1.5rem;
            width: 44px;
            height: 44px;
            border-radius: 50%;
            background: rgba(139,92,246,0.85);
            backdrop-filter: blur(8px);
            border: 1px solid rgba(168,85,247,0.4);
            color: white;
            font-size: 1.1rem;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            opacity: 0;
            transform: translateY(12px);
            transition: opacity 0.3s ease, transform 0.3s ease, background 0.2s ease;
            z-index: 400;
            pointer-events: none;
        }
        #backToTop.show {
            opacity: 1;
            transform: translateY(0);
            pointer-events: auto;
        }
        #backToTop:hover { background: rgba(168,85,247,0.95); }

        /* Header title special font */
        .v2-title { font-family: 'Zen Kaku Gothic New', 'Noto Sans TC', sans-serif; letter-spacing: 0.05em; }

        .option-card {
            transition: border-color 0.3s, box-shadow 0.3s, transform 0.15s;
            cursor: pointer;
            position: relative;
            background: rgba(26, 17, 54, 0.6);
            overflow: hidden;
        }

        .option-card:hover {
            transform: translateY(-1px);
            border-color: rgba(168, 85, 247, 0.45) !important;
            box-shadow: 0 0 18px rgba(168, 85, 247, 0.18);
        }

        .option-card:has(input:checked) {
            border-color: var(--accent-primary);
            background: rgba(139, 92, 246, 0.15);
            box-shadow: 0 0 20px var(--accent-glow) inset;
        }

        .model-card:has(input:checked) {
            border-color: #a855f7;
            background: linear-gradient(145deg, rgba(168,85,247,0.15) 0%, rgba(59,130,246,0.1) 100%);
        }

        .model-card:has(input:checked) .model-icon {
            animation: icon-pulse 2s ease-in-out infinite;
        }

        /* v56 修復（鍵盤操作可用性漏洞）：
           .option-card／.model-card 底下實際的 radio/checkbox 都是視覺隱藏
           的（class="peer sr-only"），只用旁邊看得見的卡片當作視覺呈現。
           但這裡完全沒有針對「鍵盤 Tab 移到這個隱藏輸入框」加上任何視覺
           提示——瀏覽器原生的 focus 外框會出現在那個看不見的輸入框上，
           只用鍵盤操作（不用滑鼠）的使用者完全看不到自己現在 Tab 到哪一
           個選項、有沒有選到。
           修法：用 :has(input:focus-visible) 偵測「卡片內的輸入框正被
           鍵盤 focus」，把外框直接畫在卡片本身上——只有鍵盤 Tab 才會
           觸發 :focus-visible（滑鼠點擊不會），不會讓滑鼠使用者平白多看
           到一圈外框。 */
        .option-card:has(input:focus-visible) {
            outline: 3px solid rgba(168, 85, 247, 0.85);
            outline-offset: 2px;
        }
        body.light-mode .option-card:has(input:focus-visible) {
            outline-color: rgba(107, 33, 168, 0.9);
        }

        /* v56 新增：選中方案/選項的當下，卡片本身輕輕「彈一下」，
           強化選中的回饋感，跟這次補的其他互動回饋（hover、金額脈衝）
           風格一致。用 :has(input:checked) 觸發，只會在「剛被選中」的
           那一刻播放一次（radio/checkbox 狀態不變就不會重播）。 */
        .option-card:has(input:checked) {
            animation: option-select-pop 0.35s cubic-bezier(0.34,1.56,0.64,1);
        }
        @keyframes option-select-pop {
            0%   { transform: scale(1); }
            45%  { transform: scale(1.035); }
            100% { transform: scale(1); }
        }

        /* v56 新增：template.html 服裝勾選打勾圖示的彈跳進場——這個圖示是
           每次選中都重新插入的全新 DOM 節點（template-render.js 每次都用
           innerHTML 整個重畫），所以套用 CSS animation 就會在每次真正
           「被選中」的當下自動重新播放一次，不需要額外的 JS 判斷。 */
        .check-badge-pop {
            animation: check-badge-pop-in 0.3s cubic-bezier(0.34,1.56,0.64,1);
        }
        @keyframes check-badge-pop-in {
            0%   { transform: scale(0); opacity: 0; }
            60%  { transform: scale(1.2); opacity: 1; }
            100% { transform: scale(1); opacity: 1; }
        }

        @keyframes icon-pulse {
            0%, 100% { transform: scale(1); filter: brightness(1); }
            50% { transform: scale(1.15); filter: brightness(1.3); }
        }

        /* removed old text-gradient - now in glass-panel section above */

        .tab-btn {
            position: relative;
            transition: all 0.3s ease;
        }
        .tab-btn::after {
            content: '';
            position: absolute;
            bottom: -2px;
            left: 50%;
            transform: translateX(-50%);
            width: 0;
            height: 2px;
            background: #a855f7;
            transition: width 0.3s ease;
            box-shadow: 0 0 10px #a855f7;
        }
        .tab-btn.active { color: white; }
        .tab-btn.active::after { width: 100%; }
        body.light-mode .tab-btn.active { color: #000; }

        .page-content {
            animation: fadeIn 0.4s ease-out forwards;
        }
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        /* v47：拿掉 position: sticky，改用 JS 的 initScrollFollowPanel()
           以 transform 直接控制面板位置（見 common.js），兩者一起用可能會
           互相干擾，這裡只保留 will-change 讓瀏覽器知道這個元素會頻繁變動，
           有機會提前做 GPU 加速準備、動畫更順。 */
        .sticky-summary {
            will-change: transform;
        }

        /* v45：浮動報價提示條 —— 用 position:fixed 取代不可靠的 position:sticky。
           固定在畫面右下角，捲動超過原本報價區才淡入顯示，點擊可以平滑捲回
           原本的完整報價區塊。 */
        #floatingQuoteBar {
            position: fixed;
            right: 1.25rem;
            bottom: 1.25rem;
            z-index: 400;
            display: flex;
            align-items: center;
            gap: 0.75rem;
            padding: 0.75rem 1.25rem;
            border-radius: 9999px;
            background: rgba(20, 10, 40, 0.92);
            backdrop-filter: blur(12px);
            border: 1px solid rgba(168, 85, 247, 0.4);
            box-shadow: 0 8px 30px rgba(0,0,0,0.4);
            cursor: pointer;
            opacity: 0;
            transform: translateY(16px) scale(0.96);
            pointer-events: none;
            transition: opacity 0.25s ease, transform 0.25s ease;
        }
        #floatingQuoteBar.visible {
            opacity: 1;
            transform: translateY(0) scale(1);
            pointer-events: auto;
        }
        #floatingQuoteBar:hover { border-color: rgba(168, 85, 247, 0.7); }
        #floatingQuoteBar .fqb-label {
            font-size: 0.7rem;
            color: rgba(216, 180, 254, 0.7);
            font-weight: 700;
        }
        #floatingQuoteBar .fqb-price {
            font-size: 1.15rem;
            font-weight: 900;
            color: #fff;
        }
        #floatingQuoteBar .fqb-icon {
            font-size: 0.85rem;
            color: rgba(216, 180, 254, 0.9);
        }
        body.light-mode #floatingQuoteBar {
            background: rgba(255,255,255,0.95);
            border-color: rgba(139,92,246,0.35);
        }
        body.light-mode #floatingQuoteBar .fqb-price { color: #1a1030; }
        @media (max-width: 640px) {
            #floatingQuoteBar {
                left: 1rem;
                right: 1rem;
                bottom: 0.75rem;
                justify-content: center;
            }
        }

        .qty-btn {
            background: rgba(255,255,255,0.05);
            border: 1px solid rgba(255,255,255,0.2);
            transition: all 0.2s;
        }
        .qty-btn:hover { background: var(--accent-primary); border-color: var(--accent-primary); color: white; }

        .timeline-item:last-child::before { display: none; }

        /* ── 方案規格對照表（v31 視覺優化：統一毛玻璃表頭 + 精簡配色）── */
        .plan-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: 1.25rem; }
        .plan-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 0.82rem; }

        /* 所有欄位基底 */
        .plan-table th, .plan-table td {
            padding: 0.7rem 1rem;
            text-align: center;
            border-bottom: 1px solid rgba(255,255,255,0.06);
            white-space: nowrap;
        }

        /* 首欄「規格項目」標籤 */
        .plan-table th:first-child, .plan-table td:first-child {
            text-align: left;
            white-space: normal;
            min-width: 90px;
            font-weight: 600;
            color: rgba(196,167,255,0.65);
        }

        /* 表頭統一：毛玻璃深色底 + 方案主色文字 */
        .plan-table thead tr th {
            padding-top: 1rem;
            padding-bottom: 1rem;
            font-weight: 900;
            letter-spacing: 0.03em;
            font-size: 0.88rem;
            /* 統一底色：輕透明白，去除各方案差異背景 */
            background: rgba(255,255,255,0.04);
            backdrop-filter: blur(4px);
            -webkit-backdrop-filter: blur(4px);
        }

        /* 表頭方案主色：僅文字上色 */
        .plan-table thead th.col-basic { color: #34d399; }   /* 標準方案：柔和翠綠 */
        .plan-table thead th.col-pro   { color: #38bdf8; }   /* 專業方案：科技天藍 */
        .plan-table thead th.col-top   { color: #fbbf24; }   /* 頂級方案：曜金琥珀 */

        /* hover 行高光 */
        .plan-table tbody tr:last-child td { border-bottom: none; }
        .plan-table tbody tr:hover td { background: rgba(255,255,255,0.03); }

        /* 內文一律收斂為柔白 — tbody 普通格子統一淡白，移除舊版五顏六色 */
        .plan-table tbody td {
            color: rgba(255,255,255,0.80);
        }
        .plan-table .cell-yes {
            color: rgba(255,255,255,0.90);
            font-weight: 600;
        }
        /* 加購提示保留輕暖色，但降低飽和度 */
        .plan-table .cell-add {
            color: rgba(251,191,36,0.70);
            font-size: 0.75rem;
            font-weight: 600;
        }
        /* 頂級方案「內含」標記：保留方案主色強調 */
        .plan-table .cell-incl {
            color: #fbbf24;
            font-weight: 700;
        }

        /* 起價列：字型放大 + 各方案主色顯示 */
        .plan-table .price-row td {
            font-size: 1rem;
            font-weight: 900;
            padding-top: 1rem;
            padding-bottom: 1rem;
            background: rgba(255,255,255,0.025);
        }
        .plan-table .price-row td.col-basic-val { color: #34d399; }  /* 翠綠 */
        .plan-table .price-row td.col-pro-val   { color: #38bdf8; }  /* 天藍 */
        .plan-table .price-row td.col-top-val   { color: #fbbf24; }  /* 琥珀 */

        /* 補充小字（含特殊發音、多層衣服等）統一淡灰 */
        .plan-table tbody td span[style*="color:rgba(196,167,255"] {
            color: rgba(255,255,255,0.45) !important;
        }
        
        #copyBtn:disabled, #animCopyBtn:disabled { opacity: 0.5; cursor: not-allowed; filter: grayscale(100%); }
        .btn-copy-summary:disabled { pointer-events: none; }

        /* v38：移除了從未使用過的 Google Drive 作品集骨架屏 CSS（.drive-skeleton-*
           .drive-img-fade .drive-loading-banner），目前作品展示的骨架屏用的是
           下面這一段「GIF 卡片骨架屏基底」，跟 Drive 那套完全無關。 */

        /* GIF 卡片骨架屏基底 */
        .gif-skeleton {
            background: linear-gradient(
                90deg,
                rgba(255,255,255,0.04) 0%,
                rgba(255,255,255,0.09) 40%,
                rgba(255,255,255,0.04) 80%
            );
            background-size: 200% 100%;
            animation: skeleton-shimmer 1.6s ease-in-out infinite;
            border-radius: 0.5rem;
        }
        /* v53：同樣是白色系 shimmer，在淺色模式下改用深紫色系維持可見度。 */
        body.light-mode .gif-skeleton {
            background: linear-gradient(
                90deg,
                rgba(107,33,168,0.08) 0%,
                rgba(107,33,168,0.16) 40%,
                rgba(107,33,168,0.08) 80%
            );
            background-size: 200% 100%;
        }
        @keyframes skeleton-shimmer {
            0%   { background-position: 200% center; }
            100% { background-position: -200% center; }
        }

        /* ── 作品展示頁：動態貼圖／動態Logo 卡片（v54 新增）──
           這幾張卡片原本是 portfolio-render.js 用 JS 直接寫 inline style
           （background:#0f0720 這類寫死的深色值），淺色模式的所有覆寫
           都是透過 CSS class 選擇器生效的，完全碰不到 inline style，
           所以這幾張卡片不管切換到深色還是淺色模式，看起來都還是
           深色版本。改成用這裡的 CSS class 定義基礎樣式，讓淺色模式的
           覆寫規則可以正常生效；每張卡片各自的重點色（貼圖=翠綠／
           Logo=琥珀）改用 CSS 自訂屬性 --port-accent 帶入，這個顏色在
           兩個主題下都一樣顯眼，不需要跟著主題切換。 */
        .port-gif-card {
            background: #0f0720;
            border: 1px solid rgba(255,255,255,0.07);
            border-radius: 1rem;
            overflow: hidden;
            cursor: pointer;
            transition: border-color .25s, box-shadow .25s;
        }
        .port-gif-card:hover {
            border-color: var(--port-accent, rgba(168,85,247,0.35));
            box-shadow: 0 0 16px var(--port-accent-shadow, rgba(168,85,247,.12));
        }
        body.light-mode .port-gif-card {
            background: rgba(250, 247, 255, 0.94);
            border-color: rgba(107, 33, 168, 0.35);
        }
        .port-gif-wrap:not(.gif-skeleton) {
            background: #0c0618;
        }
        .port-gif-wrap {
            width: 100%;
            aspect-ratio: 1;
            overflow: hidden;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
        }
        body.light-mode .port-gif-wrap:not(.gif-skeleton) {
            background: rgba(235, 228, 250, 0.85);
        }
        .port-gif-label {
            font-size: .72rem;
            font-weight: 700;
            color: #e9d5ff;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            border-radius: .4rem;
            padding: .15rem .45rem;
            text-align: center;
        }
        body.light-mode .port-gif-label {
            color: #3b1f6e;
        }
        .port-gif-sub {
            font-size: .62rem;
            color: rgba(196,167,255,.45);
            margin-top: .2rem;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            text-align: center;
        }
        body.light-mode .port-gif-sub {
            color: rgba(90, 50, 140, 0.65);
        }

        /* GIF 圖片：載入完成後淡入 */
        .gif-img-fade {
            opacity: 0;
            transition: opacity 0.45s ease;
        }
        .gif-img-fade.loaded {
            opacity: 1;
        }

        /* v51：把上面 GIF 專用的「載入完成才淡入」邏輯抽成通用版本
           （.img-fade），提供給其他一般圖片共用，例如合作繪師頭像——這些
           頭像是 loading="lazy"，捲到才會真的觸發下載，如果沒有這個效果，
           圖片下載完成的瞬間會直接「唰」一聲蹦出來，跟外層卡片已經很平順
           的淡入動畫比起來顯得突兀。 */
        .img-fade {
            opacity: 0;
            transition: opacity 0.45s ease;
        }
        .img-fade.loaded {
            opacity: 1;
        }

        /* v38：移除了 .gif-wrap-frozen 規則，這是舊版「視窗外 GIF 用
           IntersectionObserver 凍結」機制的殘留樣式，該機制本身已經被
           拿掉（見 portfolio-render.js 開頭的說明），沒有任何地方會再
           加上 gif-wrap-frozen 這個 class。 */

        /* ══════════════════════════════════════════════════
           📱 v27 行動裝置：iOS 滾動硬體加速
           ══════════════════════════════════════════════════ */
        html, body {
            -webkit-overflow-scrolling: touch;
        }

        /* 確保主要可滾動容器都有 iOS 回彈效果 */
        main, .page-content, #page-portfolio, #page-anim, #page-core {
            -webkit-overflow-scrolling: touch;
        }

        /* ══════════════════════════════════════════════════
           📱 v27 行動裝置：表格與計算機響應式修復
           ══════════════════════════════════════════════════ */
        @media (max-width: 767px) {
            /* 方案規格對照表 — 橫向可滑動 */
            .plan-table-wrap {
                overflow-x: auto !important;
                -webkit-overflow-scrolling: touch !important;
                max-width: 100vw;
            }
            .plan-table {
                min-width: 480px; /* 確保表格不壓縮到破版 */
            }

            /* 計算機選項卡：手機上改為上下堆疊 */
            #page-core .grid-cols-3,
            #page-anim .grid-cols-3 {
                grid-template-columns: 1fr !important;
            }

            /* 計算機細節欄位：手機上改為單欄 */
            #page-core .md\:grid-cols-2,
            #page-anim .md\:grid-cols-2 {
                grid-template-columns: 1fr !important;
            }

            /* 報價區塊：手機全寬（含聯名模板）*/
            #page-core .lg\:w-1\/3,
            #page-anim .lg\:w-1\/3,
            #page-template .lg\:w-1\/3 {
                width: 100% !important;
            }
            #page-core .lg\:w-2\/3,
            #page-anim .lg\:w-2\/3,
            #page-template .lg\:w-2\/3 {
                width: 100% !important;
            }
            #page-core .lg\:flex-row,
            #page-anim .lg\:flex-row {
                flex-direction: column !important;
            }
            #page-template {
                flex-direction: column !important;
            }

            /* GIF 作品集：手機改為 2 欄，避免 4 欄太小 */
            #gif-grid-stickers,
            #gif-grid-logos {
                grid-template-columns: repeat(2, 1fr) !important;
            }

            /* 按鈕不讓文字換行溢出 */
            .ulb-arrow {
                font-size: 1.5rem !important;
                padding: 0 0.5rem !important;
            }
        }

        /* 動畫效果：尊重系統「減少動態效果」設定 */
        @media (prefers-reduced-motion: reduce) {
            *, *::before, *::after {
                animation-duration: 0.01ms !important;
                animation-iteration-count: 1 !important;
                transition-duration: 0.01ms !important;
            }
            #meteor-canvas { opacity: 0 !important; }
            .reveal { opacity: 1 !important; transform: none !important; }
        }

        /* 流星動畫 */
        #meteor-canvas {
            position: fixed;
            top: 0; left: 0;
            width: 100%; height: 100%;
            pointer-events: none;
            z-index: 0;
            opacity: 1;
            transition: opacity 0.8s ease;
            will-change: transform;   /* 提升至獨立 GPU layer，避免與 DOM repaint 互搶 */
            contain: strict;          /* 限制 layout/paint 範圍到 canvas 本身 */
        }
        body > header, body > main, body > div { position: relative; z-index: 1; }
        .fixed { z-index: 50 !important; }

        /* 氣泡對話 */
        .speech-bubble {
            position: absolute;
            background: rgba(30, 10, 60, 0.95);
            border: 1px solid rgba(168,85,247,0.5);
            border-radius: 1rem;
            padding: 0.5rem 0.9rem;
            font-size: 0.78rem;
            font-weight: 700;
            color: #e9d5ff;
            white-space: nowrap;
            pointer-events: none;
            z-index: 20;
            animation: bubble-pop 2.5s ease forwards;
            box-shadow: 0 4px 20px rgba(168,85,247,0.3);
            top: -10px; left: 50%; transform: translateX(-50%);
        }
        .speech-bubble::after {
            content: '';
            position: absolute;
            bottom: -8px; left: 50%; transform: translateX(-50%);
            border: 8px solid transparent;
            border-top-color: rgba(168,85,247,0.5);
            border-bottom: 0;
        }
        @keyframes bubble-pop {
            0% { opacity: 0; transform: translateX(-50%) translateY(8px) scale(0.8); }
            15% { opacity: 1; transform: translateX(-50%) translateY(-4px) scale(1.05); }
            25% { transform: translateX(-50%) translateY(0) scale(1); }
            70% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
            100% { opacity: 0; transform: translateX(-50%) translateY(-10px) scale(0.9); }
        }
        .avatar-click { cursor: pointer; transition: transform 0.2s; user-select: none; }
        .avatar-click:hover { transform: scale(1.05); }
        .avatar-click:active { transform: scale(0.95); }
        body.light-mode .speech-bubble { background: rgba(210,190,245,0.97); color: #1a1030; border-color: rgba(100,60,150,0.5); }

        /* ===== V4 創意加強樣式（shimmer 光澤掃過效果，跟上面 .option-card 主要樣式合併整理過） ===== */
        .option-card::before { content: ''; position: absolute; inset: 0; border-radius: inherit; background: linear-gradient(120deg, transparent 30%, rgba(168,85,247,0.22) 50%, transparent 70%); transform: translateX(-120%); pointer-events: none; transition: none; }
        .option-card:hover::before { transform: translateX(120%); transition: transform 0.5s ease; }

        /* Nav dropdown */
		.nav-dropdown-open #commArrow { transform: rotate(180deg); }
		.nav-dropdown-open #creativeArrow { transform: rotate(180deg); }
		#commDropdown, #creativeDropdown { transform-origin: top left; background: #120824; border-color: rgba(139,92,246,0.4); max-height: 80vh; overflow-y: auto; }
		@media (max-width: 640px) {
		#commDropdown, #creativeDropdown { left: 50%; transform: translateX(-50%); }
		}
        /* 白天模式下拉選單修復 */
        body.light-mode #commDropdown,
        body.light-mode #creativeDropdown {
            background: rgba(225, 215, 245, 0.99) !important;
            border-color: rgba(130, 80, 190, 0.40) !important;
            box-shadow: 0 8px 30px rgba(80, 40, 140, 0.18) !important;
        }
        body.light-mode #commDropdown button,
        body.light-mode #creativeDropdown button {
            color: #3b1f6e !important;
        }
        body.light-mode #commDropdown button:hover,
        body.light-mode #creativeDropdown button:hover {
            background: rgba(130, 80, 190, 0.15) !important;
            color: #1a1030 !important;
        }

        /* ── 統一燈箱 ── */
        #unifiedLightbox {
            display: none;
            position: fixed;
            top: 0; left: 0;
            width: 100vw; height: 100vh;
            background: rgba(0,0,0,0.92);
            backdrop-filter: blur(12px);
            -webkit-backdrop-filter: blur(12px);
            z-index: 99999;
            align-items: center;
            justify-content: center;
        }
        #unifiedLightbox.open { display: flex; }
        #ulbImg {
            max-width: min(88vw, 720px);
            max-height: 72vh;
            width: auto; height: auto;
            object-fit: contain;
            border-radius: 1rem;
            border: 1px solid rgba(168,85,247,0.25);
            box-shadow: 0 0 60px rgba(168,85,247,0.2);
            display: block;
        }

        /* ── RPG Loader ── */
        /* 同一瀏覽階段內非第一次進站：html 標籤最一開始就會被行內腳本
           加上 hakka-skip-loader（見各 html <head> 最上方），
           讓 Loader 從「第一次繪製畫面」開始就直接不顯示，
           避免『先閃一下 Loading 才消失』的卡頓感。 */
        html.hakka-skip-loader #rpgLoader { display: none !important; }
        html.hakka-skip-loader body.loading { overflow: visible; }
        #rpgLoader {
            position: fixed; inset: 0; z-index: 99999;
            background: #07010f;
            display: flex; flex-direction: column;
            align-items: center; justify-content: center;
            gap: 0;
            transition: opacity 0.6s ease;
        }
        #rpgLoader.fade-out { opacity: 0; pointer-events: none; }
        body.loading { overflow: hidden; }
        .rpg-title {
            font-size: 1.5rem; font-weight: 900; letter-spacing: 0.18em;
            background: linear-gradient(90deg, #c084fc, #818cf8, #c084fc);
            background-size: 200% auto;
            -webkit-background-clip: text; -webkit-text-fill-color: transparent;
            animation: rpgShimmer 2.5s linear infinite;
            margin-bottom: 2.5rem;
            text-align: center;
        }
        #rpgCatImg {
            width: 96px; height: 96px;
            image-rendering: pixelated;
            image-rendering: crisp-edges;
            margin-bottom: 1.4rem;
            animation: rpgBob 1.2s ease-in-out infinite alternate;
            filter: drop-shadow(0 0 14px rgba(192,132,252,0.8));
        }
        .rpg-bar-wrap {
            width: 280px; height: 10px;
            background: rgba(255,255,255,0.06);
            border-radius: 99px;
            border: 1px solid rgba(168,85,247,0.3);
            overflow: hidden;
            position: relative;
        }
        .rpg-bar-fill {
            height: 100%; width: 0%;
            border-radius: 99px;
            background: linear-gradient(90deg, #7c3aed, #a855f7, #c084fc);
            box-shadow: 0 0 10px rgba(168,85,247,0.8);
            transition: width 0.12s linear;
        }
        .rpg-bar-glow {
            position: absolute; top: 0; right: 0; width: 40px; height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4));
            animation: rpgGlow 0.8s ease-in-out infinite alternate;
        }
        .rpg-status {
            margin-top: 0.85rem;
            font-size: 0.7rem; letter-spacing: 0.18em;
            color: rgba(192,132,252,0.6);
            text-transform: uppercase;
            min-height: 1.2em;
            transition: color 0.3s;
        }
        .rpg-dots { display: flex; gap: 6px; margin-top: 1.8rem; }
        .rpg-dot {
            width: 5px; height: 5px; border-radius: 50%;
            background: rgba(168,85,247,0.25);
            animation: rpgPulse 1.2s ease-in-out infinite;
        }
        .rpg-dot:nth-child(2) { animation-delay: 0.2s; }
        .rpg-dot:nth-child(3) { animation-delay: 0.4s; }
        @keyframes rpgShimmer { to { background-position: 200% center; } }
        @keyframes rpgBob { from { transform: translateY(0); } to { transform: translateY(-6px); } }
        @keyframes rpgGlow { from { opacity: 0.3; } to { opacity: 1; } }
        @keyframes rpgPulse {
            0%, 100% { background: rgba(168,85,247,0.25); transform: scale(1); }
            50% { background: rgba(192,132,252,0.9); transform: scale(1.4); }
        }
        #ulbLabel { color:rgba(255,255,255,0.55); font-size:0.75rem; letter-spacing:0.1em; margin-top:10px; }
        .ulb-arrow {
            position: absolute; top: 50%; transform: translateY(-50%);
            width: 44px; height: 44px; border-radius: 50%;
            background: rgba(168,85,247,0.25); border: 1px solid rgba(168,85,247,0.4);
            color: white; font-size: 1.1rem;
            display: flex; align-items: center; justify-content: center;
            cursor: pointer; transition: background 0.2s, transform 0.15s;
            z-index: 10;
        }
        .ulb-arrow:hover { background: rgba(168,85,247,0.5); transform: translateY(-50%) scale(1.1); }
        #ulbPrev { left: 16px; }
        #ulbNext { right: 16px; }
        #ulbDots { display:flex; gap:6px; justify-content:center; margin-top:12px; }
        .ulb-dot {
            width:7px; height:7px; border-radius:50%;
            background: rgba(255,255,255,0.25); cursor: pointer;
            transition: background 0.2s, transform 0.2s;
        }
        .ulb-dot.active { background:#a855f7; transform: scale(1.35); }

        /* ── 推薦頻道卡片 ── */
        .ch-card {
            display: flex;
            flex-direction: column;
            height: 100%;
        }
        .ch-card-body {
            display: flex;
            gap: 1rem;
            flex: 1;
        }
        .ch-avatar-wrap {
            width: 64px; height: 64px;
            border-radius: 50%;
            overflow: hidden;
            flex-shrink: 0;
            display: flex; align-items: center; justify-content: center;
        }
        .ch-info {
            flex: 1;
            min-width: 0;
            display: flex;
            flex-direction: column;
        }
        .ch-name {
            font-weight: 900;
            color: white;
            font-size: 0.95rem;
            margin-bottom: 0.35rem;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .ch-bio {
            font-family: inherit, 'Noto Emoji', sans-serif;
            font-size: 0.72rem;
            color: rgba(196, 181, 253, 0.65);
            line-height: 1.55;
            /* 固定 4 行高度，超出截斷 */
            display: -webkit-box;
            -webkit-line-clamp: 4;
            -webkit-box-orient: vertical;
            overflow: hidden;
            min-height: calc(1.55em * 4);
        }
        .ch-links {
            display: flex;
            flex-wrap: wrap;
            gap: 0.5rem;
            margin-top: 0.85rem;
            padding-top: 0.75rem;
            border-top: 1px solid rgba(255,255,255,0.08);
        }

        /* ── Ko-fi 贊助按鈕 ── */
        .kofi-btn {
            display: inline-flex;
            align-items: center;
            gap: 0.5rem;
            padding: 0.55rem 1.1rem;
            border-radius: 99px;
            background: linear-gradient(135deg, #ff5e5b, #ff8c42);
            color: white;
            font-weight: 700;
            font-size: 0.82rem;
            transition: all 0.2s;
            box-shadow: 0 4px 14px rgba(255,94,91,0.35);
            white-space: nowrap;
        }
        .kofi-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(255,94,91,0.5);
            filter: brightness(1.08);
        }
        .kofi-btn svg {
            width: 1.1em;
            height: 1.1em;
            flex-shrink: 0;
        }


        /* 合作繪師：語言切換顯示控制 */
        .artist-name { display: inline; }
        .artist-id   { display: none; color: rgba(196,181,253,0.6); font-size: 0.82em; font-weight: 400; }
        html[lang='en']  .artist-name,
        html[lang='ja']  .artist-name { display: none; }
        html[lang='en']  .artist-id,
        html[lang='ja']  .artist-id   { display: inline; }

        /* ── 頻道平台大按鈕 ── */
        .ch-platform-btn {
            display: flex;
            align-items: center;
            gap: 0.6rem;
            padding: 0.55rem 0.9rem;
            border-radius: 0.75rem;
            font-weight: 700;
            font-size: 0.8rem;
            transition: all 0.2s;
            flex: 1;
            min-width: 0;
            position: relative;
            overflow: hidden;
        }
        .ch-platform-btn .btn-platform-icon {
            font-size: 1.1rem;
            flex-shrink: 0;
        }
        .ch-platform-btn .btn-label {
            flex: 1;
            min-width: 0;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        .ch-platform-btn .btn-status {
            display: inline-flex;
            align-items: center;
            gap: 0.25rem;
            font-size: 0.62rem;
            font-weight: 700;
            padding: 0.15rem 0.45rem;
            border-radius: 99px;
            flex-shrink: 0;
            letter-spacing: 0.03em;
        }
        /* Twitch 按鈕 */
        .ch-platform-btn.twitch {
            background: rgba(145, 70, 255, 0.1);
            border: 1px solid rgba(145, 70, 255, 0.28);
            color: #c4b5fd;
        }
        .ch-platform-btn.twitch:hover {
            background: rgba(145, 70, 255, 0.22);
            border-color: rgba(145, 70, 255, 0.55);
            color: white;
            transform: translateY(-1px);
        }
        .ch-platform-btn.twitch .btn-status.offline {
            background: rgba(107,114,128,0.25);
            color: rgba(156,163,175,0.9);
        }
        .ch-platform-btn.twitch .btn-status.online {
            background: rgba(239,68,68,0.22);
            color: #f87171;
        }
        /* YouTube 按鈕 */
        .ch-platform-btn.youtube {
            background: rgba(220, 38, 38, 0.1);
            border: 1px solid rgba(220, 38, 38, 0.28);
            color: #fca5a5;
        }
        .ch-platform-btn.youtube:hover {
            background: rgba(220, 38, 38, 0.22);
            border-color: rgba(220, 38, 38, 0.55);
            color: white;
            transform: translateY(-1px);
        }
        .ch-platform-btn.youtube .btn-status.offline {
            background: rgba(107,114,128,0.25);
            color: rgba(156,163,175,0.9);
        }
        .ch-platform-btn.youtube .btn-status.online {
            background: rgba(239,68,68,0.22);
            color: #f87171;
        }
        /* 直播中 dot 動畫 */
        .status-dot {
            width: 5px; height: 5px;
            border-radius: 50%;
            background: currentColor;
            flex-shrink: 0;
        }
        .btn-status.online .status-dot {
            box-shadow: 0 0 4px currentColor;
            animation: live-pulse 1.8s ease-in-out infinite;
        }
        @keyframes live-pulse {
            0%, 100% { opacity: 1; }
            50% { opacity: 0.7; }
        }
        @media (max-width: 640px) {
            .ulb-arrow { width: 36px; height: 36px; font-size: 0.9rem; }
            #ulbPrev { left: 8px; }
            #ulbNext { right: 8px; }
        }

/* ── template 頁面專屬樣式（原第二個 <style> 區塊）── */
    /* ── 衣裝圖片卡片 hover 互動 ── */
    .tmpl-card-hover:hover {
        transform: translateY(-3px) scale(1.04);
        box-shadow: 0 8px 28px rgba(168,85,247,0.35), 0 0 0 2px rgba(192,68,255,0.55);
        border-color: rgba(192,68,255,0.7) !important;
    }
    .tmpl-card-hover:hover img {
        transform: translate3d(0,0,0) scale(1.08);
    }
    .tmpl-card-hover:hover .tmpl-hover-glow {
        opacity: 1 !important;
    }
    .tmpl-card-hover:active {
        transform: translateY(-1px) scale(1.01);
        transition-duration: 0.08s;
    }

    /* 衣裝 Checkbox 卡片 */
    .tmpl-outfit-check {
        display: flex; align-items: center; gap: 0.5rem;
        padding: 0.5rem 0.75rem; border-radius: 0.75rem;
        font-size: 0.8rem; font-weight: 700; cursor: pointer;
        border: 1px solid rgba(255,255,255,0.1);
        background: rgba(255,255,255,0.03);
        color: rgba(196,181,253,0.75);
        transition: all 0.2s cubic-bezier(0.4,0,0.2,1);
        user-select: none;
    }
    .tmpl-outfit-check:hover {
        border-color: rgba(192,68,255,0.5);
        background: rgba(192,68,255,0.1);
        color: white;
    }
    .tmpl-outfit-check.active {
        background: linear-gradient(135deg, rgba(192,68,255,0.28) 0%, rgba(99,102,241,0.18) 100%);
        border-color: rgba(232,121,249,0.7);
        color: white;
        box-shadow: 0 0 14px rgba(192,68,255,0.25) inset;
    }
    .tmpl-outfit-check .check-box {
        width: 1.1rem; height: 1.1rem; border-radius: 0.3rem;
        border: 1.5px solid rgba(192,68,255,0.45);
        display: flex; align-items: center; justify-content: center;
        flex-shrink: 0; transition: all 0.2s;
        background: transparent;
    }
    .tmpl-outfit-check.active .check-box {
        background: rgba(192,68,255,0.85);
        border-color: rgba(232,121,249,0.9);
    }
