  :root {
    /* 乾淨的淺灰白背景 */
    --bg-top: #F7F9FA;
    --bg-bottom: #F7F9FA;
    /* 更柔和深邃的文字顏色 */
    --ink: #2C3E50;
    --ink-soft: #8395A7;
    /* 現代感的明亮強調色（接近 TypingClub 的藍） */
    --accent: #0082F3;
    --accent-soft: #E6F3FF;
    /* 打字狀態顏色優化 */
    --good: #10AC84;
    --good-soft: #E1F7EF;
    --bad: #EE5253;
    --bad-soft: #FDEDED;
    /* 鍵盤與區塊背景 */
    --tray: #FFFFFF;
    --key-face: #FFFFFF;
    --key-edge: #EAECEF; /* 邊框變得非常淡 */
    --key-text: #485460;

    /* 保留原有的指法顏色，但你可以視需求調淡 */
    --f-lp:#C97070; --f-lr:#D79A5D; --f-lm:#C9AE55; --f-li:#6FA37D;
    --f-ri:#4C93A0; --f-rm:#4E77AC; --f-rr:#6E63A6; --f-rp:#9C5C8C; --f-thumb:#A9B4BF;

    --font-display: 'Nunito', 'Quicksand', 'Noto Sans TC', sans-serif; /* 推薦加入 Nunito 增加圓潤可愛感 */
    --font-body: 'Inter', 'Noto Sans TC', sans-serif;
  }



  *{box-sizing:border-box;}
  html,body{margin:0;padding:0;height:100%;}
  body {
    font-family: var(--font-body);
    color: var(--ink);
    background: var(--bg-top);
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: flex-start;
    padding: clamp(12px, 2.5vh, 28px) clamp(10px, 2vw, 16px) clamp(16px, 3vh, 40px);
  }

  .app{
    width:100%;
    max-width:1040px; /* 【修改】原 920px：整體版面太窄，要打的字跟鍵盤都被壓縮，改寬一點讓兩者都有更多呼吸空間 */
    display:flex;
    flex-direction:column;
    gap:clamp(10px, 1.8vh, 18px);
  }
  /* 【新增】practiceView 只是把練習畫面包起來方便整塊切換顯示的容器，本身沒有版面樣式，
     導致裡面的句子框／字卡進度／鍵盤等區塊全部黏在一起、沒有留白；補上跟 .app 一樣的直排間距，
     讓包起來之後的視覺間距跟原本沒有這層包裝時一致 */
  .practice-view{
    display:flex;
    flex-direction:column;
    gap:clamp(10px, 1.8vh, 18px);
  }

  /* ---------- Top bar ---------- */
  .topbar{
    display:flex;
    align-items:center;
    flex-wrap:wrap;
    gap:14px;
  }
  /* 【新增】左上角三條線的選單圖示，取代原本點標題才能開設定的隱藏互動 */
  .menu-btn{
    width:36px;height:36px;
    flex:none;
    display:inline-flex;
    align-items:center;
    justify-content:center;
    border:1px solid var(--accent-soft);
    border-radius:9px;
    background:#fff;
    color:var(--ink-soft);
    cursor:pointer;
    transition:background .15s ease, color .15s ease;
  }
  .menu-btn:hover{background:var(--accent-soft);color:var(--accent);}
  .menu-btn svg{width:18px;height:18px;}
  /* 【修改】標題文字重新變回可點擊：點擊會回到練習首頁（等同「返回練習」），
     所以加回 cursor:pointer 與 hover 變色，跟 .menu-btn 的視覺邏輯一致 */
  .brand{
    font-family:var(--font-display);
    font-weight:700;
    font-size:22px;
    color:var(--ink);
    letter-spacing:.02em;
    flex:none;
    white-space:nowrap;
    cursor:pointer;
    transition:color .15s ease;
  }
  .brand:hover{color:var(--accent);}
  .stats{
    display:flex;
    align-items:center;
    flex-wrap:wrap;
    gap:22px;
    font-family:var(--font-display);
    font-weight:600;
    font-size:16px;
  }
  .stat{display:flex;align-items:center;gap:6px;color:var(--ink-soft);transition:opacity .2s ease;}
  /* 除了時間以外的統計（得分/正確/錯誤/正確率/速度/連擊）一律不在頂部顯示，
     只保留在 JS 內部運算；成績改為時間到時，於左側吉祥物泡泡（bubbleEnded）一次揭曉 */
  .stats .stat:not(.time){
    display:none;
  }
  .stat .num{color:var(--ink);font-size:17px;min-width:1ch;}
  .stat.time .num{
    min-width:4.2ch;
    display:inline-block;
    text-align:left;
    font-variant-numeric:tabular-nums;
  }
  .stat.correct .num{color:var(--good);}
  .stat.wrong .num{color:var(--bad);}
  .stat.accuracy .num{color:var(--accent);}
  .stat.streak .num{color:#C9852F;}
  .stat.speed .num{color:var(--f-rr);}
  .stat svg{width:16px;height:16px;flex:none;}

  /* 【修改】原本的課程選單／操作鈕／時間列，包成一組可以在切到「打字紀錄」頁時整塊隱藏的容器；
     改用 flex:1 撐滿標題右側剩餘空間，讓內部的 .topbar-right 能用 margin-left:auto 推到最右邊 */
  .topbar-controls{display:flex;align-items:center;flex-wrap:wrap;gap:14px;flex:1;min-width:0;}
  /* 【新增】課程／小課程合併成一個一體成形的選單群組：外層統一一個邊框，中間用細直線分隔，取代原本兩個各自獨立的白底方框 */
  .control-group {
    display: flex;
    align-items: stretch;
    background: #fff;
    border: none; 
    border-radius: 12px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.04);
    overflow: hidden;
    transition: box-shadow 0.15s ease;
  }
  /* 【新增】對焦時（點開下拉選單）在整個群組外層加圓角光暈，取代瀏覽器預設、跟圓角對不齊的黑色方形外框 */
  .control-group:focus-within {
    box-shadow: 0 0 0 3px var(--accent-soft);
  }
  .control-group select{
    outline:none;
  }
  .control-group .lesson-select{
    border:none;
    border-radius:0;
  }
  .control-group .course-select{
    background:var(--accent-soft);
  }
  .control-divider {
    width: 1px;
    flex: none;
    background: #F1F2F6; /* 非常淡的分隔線 */
  }
  /* 【修改】開始／重新開始等操作鈕獨立成一組，跟課程選單、時間之間用 gap 拉開，不再擠成一長串同樣式的按鈕 */
  .session-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
  /* 【新增】右上角「時間＋開始/重設」群組：用 margin-left:auto 推到 .topbar-controls 最右側 */
  .topbar-right{
    display:flex;
    align-items:center;
    gap:14px;
    flex-wrap:wrap;
    margin-left:auto;
  }
  /* 【修改】「打字紀錄」現在移進設定側欄裡當一般選項，維持低調的 ghost 樣式即可，不再需要跟主按鈕搶視覺焦點的切換邏輯 */
  .btn-ghost{
    background:transparent;
    border-color:transparent;
    color:var(--ink-soft);
  }
  .btn-ghost:hover{background:var(--accent-soft);color:var(--accent);}
  .btn{
    font-family:var(--font-body);
    font-weight:500;
    font-size:14px;
    color:var(--accent);
    background:#fff;
    border:1px solid var(--accent-soft);
    padding:8px 14px;
    border-radius:9px;
    cursor:pointer;
    transition:background .15s ease, transform .1s ease;
  }
  .btn:hover{background:var(--accent-soft);}
  .btn:active{transform:translateY(1px);}
  .btn.primary{background:var(--accent);color:#fff;border-color:var(--accent);}
  .btn.primary:hover{background:#28608f;}
  .btn:disabled{opacity:.5;cursor:not-allowed;} /* 【新增】按鈕被鎖住時（例如氣球遊戲中鍵盤開關暫時失效）的樣式 */
  .btn:disabled:hover{background:#fff;}

  .lesson-select{
    font-family:var(--font-body);
    font-weight:500;
    font-size:14px;
    color:var(--accent);
    background:#fff;
    border:1px solid var(--accent-soft);
    padding:8px 10px;
    border-radius:9px;
    cursor:pointer;
  }
  /* 【新增】兩層課程選單：左邊「大課程」（英打／注音）、右邊「小課程」（該大課程底下的課程） */
  .course-select{
    font-weight:700;
    background:var(--accent-soft);
  }

  /* 【新增】小課程自訂下拉選單：取代原生 select，讓展開清單的高度可以用 CSS 控制（限制在畫面 80% 高，超過就內部捲動） */
  .lesson-dropdown{
    position:relative;
    display:flex;
  }
  .lesson-dropdown-btn{
    display:flex;
    align-items:center;
    gap:8px;
    height:100%;
  }
  .lesson-dropdown-caret{
    width:14px;
    height:14px;
    flex:none;
    color:var(--ink-soft);
    transition:transform .15s ease;
  }
  .lesson-dropdown.open .lesson-dropdown-caret{
    transform:rotate(180deg);
  }
  .lesson-dropdown-menu{
    /* 【修改】原本用 position:absolute，但父層 .control-group 有 overflow:hidden（用來裁出一體成形的圓角外框），
       會連同這個下拉清單一起裁掉，導致清單「展開了但看不到」；改成 position:fixed，
       不受 .control-group 的 overflow:hidden 影響，展開位置改由 JS 依按鈕位置動態計算（見下方 open 事件） */
    position:fixed;
    background:#fff;
    border:1px solid var(--accent-soft);
    border-radius:12px;
    box-shadow:0 16px 34px -16px rgba(35,50,65,.4);
    padding:6px;
    display:none;
    flex-direction:column;
    min-width:220px;
    max-height:80vh;
    overflow-y:auto;
    z-index:20;
  }
  .lesson-dropdown.open .lesson-dropdown-menu{
    display:flex;
  }
  .lesson-dropdown-group{
    font-family:var(--font-body);
    font-size:12px;
    font-weight:700;
    color:var(--accent);
    padding:10px 10px 4px;
  }
  .lesson-dropdown-item{
    font-family:var(--font-body);
    font-size:13px;
    font-weight:500;
    color:var(--ink);
    padding:7px 12px;
    border-radius:7px;
    cursor:pointer;
    white-space:nowrap;
    transition:background .12s ease;
  }
  .lesson-dropdown-item:hover{background:var(--accent-soft);color:var(--accent);}
  .lesson-dropdown-item.selected{background:var(--accent);color:#fff;}

  /* ---------- Sidebar（設定＋說明，取代原本的下拉設定面板） ---------- */
  .sidebar-overlay{
    position:fixed;
    inset:0;
    background:rgba(35,50,65,.28);
    opacity:0;
    pointer-events:none;
    transition:opacity .2s ease;
    z-index:20;
  }
  .sidebar-overlay.open{opacity:1;pointer-events:auto;}
  .sidebar{
    position:fixed;
    top:0;left:0;
    height:100%;
    width:min(320px,86vw);
    background:var(--tray);
    box-shadow:18px 0 40px -20px rgba(35,50,65,.35);
    transform:translateX(-100%);
    transition:transform .25s ease;
    z-index:21;
    display:flex;
    flex-direction:column;
    overflow-y:auto;
  }
  .sidebar.open{transform:translateX(0);}
  .sidebar-header{
    display:flex;
    align-items:center;
    justify-content:space-between;
    padding:18px 20px 12px;
    border-bottom:1px solid #E1EBF3;
  }
  .sidebar-header .title{
    font-family:var(--font-display);
    font-weight:700;
    font-size:17px;
    color:var(--ink);
  }
  .sidebar-close{
    width:30px;height:30px;
    border-radius:50%;
    border:1px solid var(--accent-soft);
    background:#fff;
    color:var(--ink-soft);
    font-size:16px;
    line-height:1;
    cursor:pointer;
  }
  .sidebar-close:hover{background:var(--accent-soft);color:var(--accent);}
  .sidebar-section{
    padding:16px 20px;
    border-bottom:1px solid #E1EBF3;
  }
  .sidebar-section:last-child{border-bottom:none;}
  /* 【新增】設定側欄裡的「打字紀錄」按鈕：撐滿寬度，跟其他設定項目一樣用區塊呈現 */
  .sidebar-history-btn{
    width:100%;
    display:flex;
    align-items:center;
    justify-content:center;
    gap:6px;
  }
  .sidebar-section .section-title{
    font-family:var(--font-display);
    font-weight:700;
    font-size:13px;
    color:var(--ink-soft);
    text-transform:uppercase;
    letter-spacing:.04em;
    margin-bottom:12px;
  }
  /* 【新增】可摺疊的區塊標題（目前只有「指法顏色說明」用到）：整列可點擊，右側箭頭依展開狀態旋轉 */
  .section-title.collapsible{
    width:100%;
    display:flex;
    align-items:center;
    justify-content:space-between;
    background:none;
    border:none;
    padding:0;
    cursor:pointer;
    font-family:inherit;
    font-weight:inherit;
    font-size:inherit;
    color:inherit;
    text-transform:inherit;
    letter-spacing:inherit;
  }
  .section-title.collapsible:hover{color:var(--accent);}
  .collapsible-caret{
    width:14px;height:14px;
    flex:none;
    transition:transform .15s ease;
  }
  .section-title.collapsible[aria-expanded="true"] .collapsible-caret{
    transform:rotate(180deg);
  }
  .sidebar-inner{
    display:flex;
    flex-direction:column;
    gap:14px;
  }
  .lesson-info-name{
    font-family:var(--font-display);
    font-weight:700;
    font-size:15px;
    color:var(--ink);
    margin-bottom:4px;
  }
  .lesson-info-desc{
    font-size:13px;
    color:var(--ink-soft);
    line-height:1.6;
  }
  .sidebar-legend{
    display:flex;
    flex-direction:column;
    gap:9px;
  }
  .sidebar-legend .legend-item{
    display:flex;
    align-items:center;
    gap:10px;
    font-size:13px;
    color:var(--ink);
  }
  .sidebar-legend .legend-item i{
    width:14px;height:14px;
    border-radius:4px;
    flex:none;
  }
  .toggle-row{display:flex;align-items:center;gap:10px;}
  .toggle-row .label{font-size:14px;color:var(--ink);font-weight:500;}
  .toggle-row .badge{
    font-size:11px;
    color:var(--ink-soft);
    background:#EEF3F8;
    border-radius:6px;
    padding:2px 6px;
    margin-left:6px;
  }
  .switch{
    position:relative;
    width:40px;height:22px;
    border-radius:20px;
    background:#D6E0E9;
    cursor:pointer;
    transition:background .15s ease;
    flex:none;
  }
  .switch.on{background:var(--accent);}
  .switch.disabled{cursor:not-allowed;opacity:.55;}
  .switch::after{
    content:"";
    position:absolute;
    top:2px;left:2px;
    width:18px;height:18px;
    border-radius:50%;
    background:#fff;
    transition:left .15s ease;
    box-shadow:0 1px 2px rgba(0,0,0,.2);
  }
  .switch.on::after{left:20px;}
  /* 【新增】字母／注音兩層至少要留一層，點擊會被擋下時的小晃動回饋 */
  .switch.locked-shake{animation:switchShake .3s ease;}
  @keyframes switchShake{
    0%,100%{transform:translateX(0);}
    25%{transform:translateX(-3px);}
    75%{transform:translateX(3px);}
  }

  /* ---------- Mascot / instruction ---------- */
  .mascot-row{
    display:flex;
    align-items:center;
    gap:16px;
    padding:6px 4px;
    position:relative;
  }
  .streak-toast{
    position:absolute;
    left:76px;
    top:-6px;
    background:var(--accent);
    color:#fff;
    font-family:var(--font-display);
    font-weight:700;
    font-size:13px;
    padding:5px 12px;
    border-radius:20px;
    box-shadow:0 6px 14px -6px rgba(46,109,164,.6);
    opacity:0;
    transform:translateY(6px);
    transition:opacity .25s ease, transform .25s ease;
    pointer-events:none;
    z-index:2;
  }
  .streak-toast.show{opacity:1;transform:translateY(0);}

  /* 【修改】亂打鎖定圖層：純淡色空白遮罩，無任何文字與秒數（時間仍繼續走） */
  .lockout-overlay{
    position:fixed;
    inset:0;
    background:rgba(234,241,247,.88);
    backdrop-filter:blur(2px);
    opacity:0;
    pointer-events:none;
    transition:opacity .25s ease;
    z-index:50;
  }
  .lockout-overlay.show{opacity:1;pointer-events:auto;}
  .mascot{width:56px;height:56px;flex:none;}
  .bubble{
    position:relative;
    background:#fff;
    border:1px solid #E1EBF3;
    border-radius:14px;
    padding:14px 18px;
    font-size:16px;
    color:var(--ink);
    line-height:1.5;
    flex:1; /* 【新增】原本沒有 flex，泡泡只跟著文字內容縮放寬度；改成填滿 mascot-row 剩餘寬度，讓結算畫面（result-grid／result-foot）能橫向撐開，減少直向高度 */
    min-width:0; /* 【新增】搭配 flex:1，避免內容（例如 result-grid）把泡泡撐爆容器寬度 */
    margin-right:clamp(28px, 6vw, 72px); /* 【新增】右側保留空間，避免結算格子貼齊最右邊；72px 約等於左側吉祥物(56px)+間距(16px)，讓左右視覺較對稱 */
  }
  .bubble::before{
    content:"";
    position:absolute;
    left:-8px;top:20px;
    width:14px;height:14px;
    background:#fff;
    border-left:1px solid #E1EBF3;
    border-bottom:1px solid #E1EBF3;
    transform:rotate(45deg);
  }
  .bubble .finger-name{color:var(--accent);font-weight:700;}
  .key-pill{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    min-width:26px;
    height:26px;
    padding:0 6px;
    border-radius:6px;
    background:var(--accent-soft);
    border:1px solid var(--accent);
    color:var(--accent);
    font-family:var(--font-display);
    font-weight:700;
    font-size:14px;
    margin:0 2px;
  }

  /* ---------- 鍵盤底部的小提示列（取代原本在對話框裡的大字「請用 X手指 按下 Y」） ---------- */
  .key-hint-bar{
    text-align:center;
    font-size:14px;
    color:var(--ink-soft);
    padding:8px 4px 2px;
  }
  .key-hint-bar .finger-name-hint{color:var(--accent);font-weight:700;}

  /* ---------- 打字小遊戲：文字賽跑（倒數時間內比距離：打對前進、打錯後退） ---------- */
  .race-track-wrap{
    display:none;
    background:var(--tray);
    border-radius:16px;
    padding:8px 14px 10px; /* 【修改】原 12px 18px 16px，整體再收斂一點 */
    box-shadow:0 14px 30px -20px rgba(35,50,65,.3), 0 2px 0 rgba(255,255,255,.6) inset;
    width:100%; /* 【新增】跟 .keyboard-tray 一樣先設 100%，才能讓下面的 max-width 生效 */
    max-width:900px; /* 【新增】原本沒有寬度上限，會撐滿整個 .app(1040px)，比下面的鍵盤(900px)還寬；改成跟鍵盤一樣的上限，兩者寬度對齊 */
    margin:0 auto; /* 【新增】變窄後置中顯示，不會偏向左邊 */
  }
  .race-track-wrap.show{display:block;}
  /* 【刪除】.race-track-header：原本獨立一列放「🏁 打字賽跑」＋「？」按鈕，
     現在跟步數合併成賽道下方的單一列 .race-info-row，不再需要賽道上方這一列 */
  /* 【新增】規則說明按鈕：圓形「？」小按鈕，取代原本常駐顯示的長句說明 */
  .race-info-btn{
    flex:none;
    width:18px;height:18px;
    border-radius:50%;
    border:1px solid var(--accent-soft);
    background:#fff;
    color:var(--ink-soft);
    font-size:11px;
    line-height:1;
    display:inline-flex;
    align-items:center;
    justify-content:center;
    cursor:pointer;
    transition:background .15s ease, color .15s ease;
  }
  .race-info-btn:hover, .race-info-btn.open{background:var(--accent-soft);color:var(--accent);}
  /* 【新增】點擊「？」按鈕才展開的規則說明小卡，預設收合 */
  .race-info-tip{
    display:none;
    font-size:12px;
    color:var(--ink-soft);
    background:var(--accent-soft);
    border-radius:8px;
    padding:6px 10px;
    margin-top:6px;
  }
  .race-info-tip.show{display:block;}
  /* 【修改】拿掉左側「你／對手」文字欄與右側疊放的步數欄，讓賽道本身（.race-track）能佔滿整條列的橫向寬度 */
  .race-lane{
    display:flex;
    align-items:center;
    margin-bottom:0; /* 【修改】原本多列才需要 margin-bottom:8px，現在只剩一列，直接拿掉 */
  }
  /* 【刪除】.race-lane-label（左側「你／對手」欄）：文字改移到賽道下方的 .race-info-row，不再占用賽道左側的橫向空間 */
  /* 【刪除】.race-lane-progress（右側疊放的步數欄）：改成賽道下方橫向排列的 .race-info-row，讓賽道左右兩端都能到底 */
  .race-track{
    position:relative;
    flex:1;
    height:40px; /* 【修改】原 34px，稍微加高以容納疊放的兩個跑者 */
    border-radius:20px;
    background:#EAF1F7;
    border:1px solid #DCE7F1;
    overflow:hidden;
  }
  /* 【修改】原本分開的「標題列」跟「步數列」合併成賽道下方單一列：
     標題／你的步數／對手步數／「？」按鈕都排在同一行，比原本兩列更省高度；
     「？」按鈕用 margin-left:auto 頂到最右邊，跟圖片參考的排版一致 */
  .race-info-row{
    display:flex;
    align-items:center;
    flex-wrap:wrap;
    gap:12px;
    margin-top:6px;
    font-family:var(--font-display);
    font-weight:600;
    font-size:12px;
    color:var(--ink-soft);
  }
  .race-title{color:var(--ink-soft);}
  .race-info-row .race-progress-item.rival{opacity:.85;}
  .race-info-row .race-info-btn{margin-left:auto;}
  .race-track .race-runner{
    position:absolute;
    top:38%;left:0%; /* 【修改】原本 top:50%，玩家跑者往上移一點，讓出下方空間給對手跑者 */
    width:26px;height:26px;
    font-size:18px;
    display:flex;align-items:center;justify-content:center;
    transform:translate(-50%,-50%);
    transition:left .25s cubic-bezier(.34,1.56,.64,1);
    z-index:2; /* 【新增】玩家永遠疊在對手上面，維持視覺焦點 */
  }
  /* 【新增】對手跑者：與玩家共用同一條跑道，用較小尺寸＋偏下的位置疊放，用顏色/大小區分、不搶焦點 */
  .race-track .race-runner-rival{
    top:74%;
    width:19px;height:19px;
    font-size:13px;
    opacity:.85;
    z-index:1;
  }
  .race-track .race-flag{
    position:absolute;
    top:50%;right:6px;
    transform:translateY(-50%);
    font-size:16px;
  }
  /* 折返跑：兩端都是折返點，跑到底自動轉向 */
  .race-track .race-flag-start{
    position:absolute;
    top:50%;left:6px;
    transform:translateY(-50%) scaleX(-1);
    font-size:16px;
  }
  /* 【刪除】.race-track-msg：原本用來顯示結算時「⏰ 時間到！你 X 步、對手 Y 步…」訊息，
     步數已經常駐顯示在賽道下方的資訊列，這則重複訊息已移除，樣式一併刪除 */

  /* ---------- Progress dots（改為「一排真實字型文字」樣式，取代彩色圓角方塊，參考 TypingClub 排版） ---------- */
  .progress-dots{
    display:flex;
    flex-wrap:wrap;
    justify-content:center; /* 【新增】換行時讓每一行都置中，避免像原本那樣多出一顆孤字卡在左邊 */
    align-items:center;
    gap:clamp(6px,1.2vw,10px); /* 【修改】原 clamp(4px,1vw,8px)，版面加寬後空間變多，字距上限跟著放寬一點 */
    padding:clamp(18px,3.4vh,32px) 6px; /* 【修改】原 8px 6px：有鍵盤時上下留白太少，跟聊天泡泡、鍵盤黏太近，改用跟視窗高度連動的上下留白 */
    font-family:'Consolas','Noto Sans TC',monospace;
  }
  .dot{
    width:auto;height:auto;
    border-radius:6px;
    border:2px solid transparent;
    display:inline-flex;align-items:center;justify-content:center;
    padding:1px 6px; /* 【修改】原 1px 4px，配合上面放寬的字距一起放大 */
    font-family:inherit;
    font-size:clamp(18px,3vw,25px); /* 【修改】原 clamp(16px,2.8vw,22px)，版面加寬後字級可以跟著放大，同時仍保留較窄的間距避免換行 */
    font-weight:500;
    color:var(--ink);
    background:transparent;
    transition:all .15s ease;
  }
  .dot.current{border-color:var(--accent);color:var(--accent);background:transparent;transform:none;}
  .dot.done{border-color:transparent;color:#C7D1DA;background:transparent;}
  .dot.space{opacity:.5;}

  /* ---------- Text passage（詞彙／句子練習：整段文字顯示模式，取代單字大字＋圓點進度） ---------- */
  .text-passage {
    display: none;
    padding: clamp(20px, 4vh, 40px) 10px;
    font-family: 'Consolas', 'Courier New', 'Noto Sans TC', monospace;
    /* 字體大幅放大，視覺更舒適 */
    font-size: clamp(24px, 4vw, 36px); 
    line-height: 1.6; 
    letter-spacing: 0.05em;
    color: var(--ink-soft);
    text-align: center; 
  }

  /* 【新增】JS 會對 #textPassage 加上 .show，但原本沒有對應的 CSS，導致單字／句子永遠是 display:none 而看不到 */
  .text-passage.show {
    display: block;
  }
  
  .text-passage .ch {
    border-radius: 6px;
    padding: 2px 4px;
    transition: all 0.15s ease;
  }

  .text-passage .ch.done {
    color: #CED6E0; 
    background: transparent;
  }

  /* 當前要打的字：加上底部粗線或柔和背景 */
  .text-passage .ch.current {
    color: var(--ink);
    background: var(--accent-soft);
    border-bottom: 3px solid var(--accent);
  }

  .text-passage .ch.current.wrong-flash {
    color: var(--bad);
    background: var(--bad-soft);
    border-bottom-color: var(--bad);
  }

  .text-passage .ch.pending {
    color: var(--ink-soft);
  }

  /* ---------- 【新增】隱藏鍵盤模式（Keyboard Guide off） ----------
     參考 TypingClub：關掉鍵盤圖後，畫面只剩「這一輪要打的完整內容」，
     字級放大、改左對齊多行排版，行距拉開，看起來就像一篇要抄打的文章 */
  body.no-keyboard .keyboard-tray{display:none;}
  body.no-keyboard .progress-dots,
  body.no-keyboard .text-passage{
    justify-content:flex-start;
    text-align:left;
    max-width:900px;
    margin:0 auto;
    padding:18px 10px;
    min-height:46vh;      /* 【新增】撐出原本鍵盤佔用的高度，切換時版面才不會整個往上跳 */
    align-content:flex-start;
  }
  body.no-keyboard .progress-dots{
    gap:10px 12px;
    row-gap:18px;
  }
  body.no-keyboard .dot{font-size:clamp(22px,3.4vw,34px);}
  body.no-keyboard .text-passage{
    font-size:clamp(22px,3.2vw,34px);
    line-height:1.9;
  }
  .balloon-sky {
    --balloon-slot: clamp(84px, 11vw, 120px);
    display: none;
    position: relative;
    
    /* 【新增】縮小遊戲範圍並置中 */
    width: 100%;
    max-width: 800px; /* 你可以根據喜好調整這個數值，例如 700px 會更緊湊，900px 會稍微寬一點 */
    margin: 0 auto;   /* 讓整個天空區塊在畫面上保持置中 */
    
    height: clamp(190px, 27vh, 270px);
    border-radius: 20px;
    overflow: hidden;
    background: linear-gradient(180deg, #8FC7EA 0%, #BBE0F2 55%, #D9F0F2 100%);
    box-shadow: 0 14px 30px -20px rgba(35, 50, 65, .45), 0 2px 0 rgba(255, 255, 255, .5) inset;
  }
  .balloon-sky.show{display:block;}
  /* 【新增】忍者抓氣球是獨立的打字遊戲，不管旁邊「顯示鍵盤」開關目前是開是關，
     這個模式一律不出現鍵盤圖，並把讓出來的高度直接給氣球天空用，
     畫面更接近 TypingClub 全螢幕氣球關卡的感覺（見下方 body.balloon-mode 覆寫）。 */
  body.balloon-mode .keyboard-tray{display:none;}
  body.balloon-mode .balloon-sky{height:clamp(460px,74vh,700px);} /* 【修改】原 clamp(400px,64vh,600px)，下面還有空間沒用到，再加大 */
  /* 裝飾用雲朵：純靜態，不做飄移動畫 */
  .balloon-cloud{
    position:absolute;
    font-size:30px;
    opacity:.55;
    pointer-events:none;
    user-select:none;
  }
  /* 【修改】忍者現在會「走路」：left 由 JS 依目前要打的氣球實際位置算好寫進 inline style，
     搭配這裡的 transition 就會滑過去；transform 平常只負責額外的小動作（打錯時往後仰）。 */
  .balloon-ninja{
    position:absolute;
    left:10px;
    bottom:12px;
    font-size:clamp(34px,5vw,46px);
    line-height:1;
    z-index:3;
    transition:left .38s cubic-bezier(.34,1.45,.64,1), transform .12s ease, opacity .2s ease; /* 【修改】原 .32s，配合下面 ninja-hop-in 動畫時間（.38s）同步拉長，水平位移跟垂直跳躍才會同時完成，看起來是同一個跳過去的動作 */
  }
  .balloon-ninja.miss{transform:translateX(-4px) rotate(-8deg);}
  /* 【修改】遊戲還沒正式開始（畫面停在「按 Space 開始」或三、二、一倒數中）時，
     忍者不再「站在」第一顆氣球上方等待（原本的 .sit 樣式已移除），改成整個藏起來，
     換成畫面左側的星號 emoji（.balloon-start-marker）佔位；等倒數結束、正式開始時才會出現並開始下降。 */
  .balloon-ninja.hide{
    opacity:0;
    pointer-events:none;
  }
  /* 【修改】忍者出場前的星號佔位符號：固定在題目左邊（跟忍者原本待命的位置一樣），
     字級跟忍者一致，讓玩家清楚知道「忍者等一下會從這裡開始下降」；
     加上 opacity 過渡，配合忍者出場時的淡入，讓「星號淡出、忍者淡入」看起來像同一個角色變身，
     而不是星號忽然消失、忍者忽然完整出現這種生硬的跳接。 */
  .balloon-start-marker{
    position:absolute;
    left:10px;
    top:22px; /* 跟 .balloon-track 的 top 對齊，讓星號跟題目（氣球排）同一列高度，而不是站在地板上 */
    font-size:clamp(34px,5vw,46px);
    line-height:1;
    z-index:3;
    pointer-events:none;
    user-select:none;
    transition:opacity .2s ease;
  }
  .balloon-start-marker.hide{opacity:0;}
  /* 【修改】忍者「跳到氣球上、然後跟著它一起慢慢掉回地板」的動畫：
     0%：從（頂端／上一顆氣球）出發 → 16%：很快跳到這顆氣球所在高度（--ride-dy 由 JS 依實際量到的位置算出）→
     100%：剩下的時間慢慢落回地板，模擬「跟氣球一起掉下去」的感覺。
     【重要】只要在這個動畫播完之前，玩家又打對下一個字，JS 就會把這個 class 移除再加回去、
     換上新的 --ride-dy 重新播一次，等於忍者立刻改跳到下一顆氣球，不必等這次真的落地——
     這就是「氣球快掉到地上前，趕快打下一個字讓忍者跳到下一顆」的效果。
     動畫時間 3s（對應「倒數三秒」）需要跟 JS 的 BALLOON_FALL_MS 常數保持一致。 */
  @keyframes ninja-ride{
    0%{ transform:translateY(var(--ninja-y-start,0)); }
    16%{ transform:translateY(var(--ride-dy,-60px)); }
    100%{ transform:translateY(0); }
  }
  .balloon-ninja.riding{
    animation:ninja-ride var(--fall-duration, 3s) cubic-bezier(.4,0,.6,1) forwards; 
  }
  /* 【新增】忍者第一次從星號位置出場時，先播這個「跳過去」的小動畫（時間跟忍者走路的 left 過渡接近，約 0.34s），
     跳到、正式站上第一顆氣球之後，才換成上面的 ninja-ride 開始真正的 3 秒落下倒數；
     取代原本「星號一開始就直接套用 ninja-ride」的寫法──因為星號跟氣球幾乎同高，
     ninja-ride 的 0%→16%（跳起）幾乎沒有變化，看起來就像「一開場就已經在往下掉」，而不是先跳過去再開始倒數。
     中間 60% 稍微跳高一點，做出「跳過去」的弧線感，跟平常落下動畫（先跳高再慢慢落下）的視覺呼應。 */
  @keyframes ninja-hop-in{
    0%{ transform:translateY(var(--ninja-y-start,0)); }
    55%{ transform:translateY(var(--hop-peak,-60px)); } /* 【修改】原本用 --ride-dy 再減 10px 當跳躍最高點，但星號跟第一顆氣球幾乎同高度時，這個高度幾乎等於起點／終點，跳躍弧線幾乎看不出來；改成用 JS 算好、保證比起點/終點都高至少 50px 的 --hop-peak，不管兩者高度多接近，都看得出明顯的「跳」 */
    100%{ transform:translateY(var(--ride-dy,-60px)); }
  }
  .balloon-ninja.hopping{
    animation:ninja-hop-in .38s cubic-bezier(.34,1.45,.64,1) forwards; /* 【修改】原 .34s，稍微拉長一點點，跟左右位移的 transition 時間（下面同步調整）搭配更明顯 */
  }
  /* 【修改】氣球排本身固定不動（不再整批位移），每顆氣球畫出來後就待在原地 */
  .balloon-track{
    position:absolute;
    left:calc(56px + clamp(34px,5vw,46px)); /* 【修改】原 10px：忍者現在一開場就站在氣球旁邊（頂端），整排題目 emoji 再往右挪一點，跟畫面左緣拉開距離 */
    right:28px; /* 搭配下面 justify-content:space-between，讓氣球平均分散到接近右邊界，不要全部擠在左半邊 */
    top:22px; /* 【修改】改回貼齊天空上方（靠上），原本 top:50%+置中是誤解；氣球排要靠上，是下面的天空空間本身要加大 */
    display:flex;
    align-items:flex-start;
    justify-content:space-between; /* 氣球平均分散在整個寬度 */
  }
  .balloon{
    position:relative;
    width:var(--balloon-slot);
    flex:none;
    display:flex;
    align-items:center;
    justify-content:center;
    font-size:clamp(46px,6.4vw,64px);
    line-height:1;
    user-select:none;
  }
  .balloon .char{
    position:absolute;
    top:32%;
    left:50%;
    transform:translate(-50%,-50%);
    font-family:var(--font-display);
    font-weight:700;
    font-size:clamp(17px,2.2vw,24px);
    color:#fff;
    text-shadow:0 1px 3px rgba(0,0,0,.45);
    pointer-events:none;
  }
  /* 目標氣球：放大＋光暈，其餘氣球稍微淡化，一眼就知道該打哪一顆 */
  .balloon.target{
    filter:drop-shadow(0 0 10px rgba(255,238,140,.95));
    transform:scale(1.12);
  }
  .balloon:not(.target){opacity:.72;}
  @keyframes balloon-shake{
    0%,100%{transform:scale(1.12) translateX(0);}
    25%{transform:scale(1.12) translateX(-6px);}
    75%{transform:scale(1.12) translateX(6px);}
  }
  .balloon.target.shake{animation:balloon-shake .28s ease;}

  .balloon.fall-floor, .balloon-start-marker.fall-floor {
    transform:translateY(var(--fall-dy,60px));
    opacity:0;
    transition:transform var(--fall-duration, 3s) cubic-bezier(.5,0,.85,.35), opacity .6s ease 1.1s; 
    pointer-events:none;
  }
  /* 右下角計數：這一輪抓到幾顆 */
  .balloon-score{
    position:absolute;
    right:14px;
    bottom:10px;
    display:flex;
    align-items:center;
    gap:6px;
    font-family:var(--font-display);
    font-weight:700;
    font-size:20px;
    color:#fff;
    text-shadow:0 1px 4px rgba(35,50,65,.45);
    z-index:3;
  }
  /* 【新增】左下角生命值：忍者與氣球一起落地一次，就扣一顆愛心；扣完 3 顆，遊戲結束 */
  .balloon-lives{
    position:absolute;
    left:14px;
    bottom:10px;
    display:flex;
    align-items:center;
    gap:2px;
    font-size:20px;
    z-index:3;
    text-shadow:0 1px 4px rgba(35,50,65,.45);
  }
  .balloon-lives .life{transition:opacity .2s ease, filter .2s ease;}
  .balloon-lives .life.lost{opacity:.28;filter:grayscale(1);}
  @keyframes lives-shake{
    0%,100%{transform:translateX(0);}
    25%{transform:translateX(-4px);}
    75%{transform:translateX(4px);}
  }
  .balloon-lives.shake{animation:lives-shake .28s ease;}
  .balloon-msg{
    position:absolute;
    left:0;right:0;
    bottom:40%;
    text-align:center;
    font-family:var(--font-display);
    font-weight:700;
    font-size:clamp(16px,2.4vw,22px);
    color:#fff;
    text-shadow:0 2px 6px rgba(35,50,65,.5);
    pointer-events:none;
    z-index:2;
  }
  .balloon-msg.hide{display:none;}

  /* ---------- 【新增】打地鼠／太空落字：共用競技場 ---------- */
  .arena{
    display:none;position:relative;
    width:100%;max-width:800px;margin:0 auto 12px;
    height:clamp(220px,34vh,320px);
    border-radius:20px;overflow:hidden;
    box-shadow:0 14px 30px -20px rgba(35,50,65,.45), 0 2px 0 rgba(255,255,255,.5) inset;
  }
  .arena.show{display:block;}
  /* 【新增】打地鼠／太空落字時不顯示鍵盤（跟忍者接氣球一樣），把讓出的高度給遊戲區，題目才不會被擠壓或遮住 */
  body.arena-mode .keyboard-tray{display:none;}
  body.arena-mode .arena{height:clamp(400px,64vh,620px);}
  body.arena-mode .arena[data-mode="whack"] .mole-face{font-size:clamp(40px,7vw,64px);}
  body.arena-mode .arena[data-mode="whack"] .mole-char{font-size:clamp(20px,3.4vw,32px);}
  body.arena-mode .drop-ship{font-size:44px;}
  .arena[data-mode="whack"]{background:linear-gradient(180deg,#CBEBB5 0%,#93CE7E 100%);}
  .arena[data-mode="drop"]{
    background:
      radial-gradient(circle,rgba(255,255,255,.8) 1px,transparent 1.5px) 0 0/46px 46px,
      radial-gradient(circle,rgba(255,255,255,.5) 1px,transparent 1.5px) 23px 23px/46px 46px,
      linear-gradient(180deg,#141B34 0%,#2B3A67 100%);
  }
  .arena-field{position:absolute;inset:0;}
  .arena-lives, .arena-score, .arena-msg{position:absolute;z-index:4;font-family:var(--font-display);color:#fff;text-shadow:0 1px 4px rgba(35,50,65,.5);}
  .arena-lives{left:14px;bottom:8px;display:flex;gap:2px;font-size:20px;}
  .arena-lives .life{transition:opacity .2s ease, filter .2s ease;}
  .arena-lives .life.lost{opacity:.28;filter:grayscale(1);}
  .arena-lives.shake{animation:lives-shake .28s ease;}
  .arena-score{right:14px;bottom:8px;font-weight:700;font-size:20px;}
  .arena-msg{left:0;right:0;top:40%;text-align:center;font-weight:700;font-size:clamp(16px,2.4vw,22px);pointer-events:none;}
  .arena-msg.hide{display:none;}

  /* 打地鼠：3×2 個洞。地鼠藏在 hole-window 裡（超出範圍被裁掉），前面蓋一圈泥土遮住切口 */
  .arena[data-mode="whack"] .arena-field{
    display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(2,1fr);
    gap:6px 18px;padding:10px 44px 34px;
  }
  .hole{position:relative;--dirt-h:clamp(40px,20%,60px);} /* 【修改】泥土高度改用固定範圍，遊戲區變高時不會跟著變成超大橢圓蓋住地鼠 */
  .hole-window{position:absolute;left:8%;right:8%;top:0;bottom:calc(var(--dirt-h) * .8);overflow:hidden;} /* bottom 24%：地鼠底部落在泥土橢圓中間，看起來是從洞裡鑽出來 */
  .mole{
    position:absolute;left:0;right:0;bottom:0;
    display:flex;flex-direction:column-reverse;align-items:center;
    transform:translateY(105%);transition:transform .16s ease-out;
  }
  .mole.up{transform:translateY(0);}
  .mole.hit{transform:translateY(18%) rotate(-8deg);filter:brightness(1.15);}
  .mole.miss{animation:lives-shake .2s ease;}
  .mole-face{font-size:clamp(32px,5.4vw,48px);line-height:1;}
  .mole-char{
    background:#fff;color:var(--ink);border:2px solid #E3C99B;border-radius:10px;
    padding:0 10px;font-weight:800;font-size:clamp(17px,2.8vw,26px);line-height:1.25;text-shadow:none;
  }
  .hole-dirt{
    position:absolute;left:2%;right:2%;bottom:0;height:var(--dirt-h);z-index:1;
    background:radial-gradient(ellipse at 50% 30%,#4A3222 0%,#6B4A2F 70%);
    border-radius:50%;
  }

  /* 太空落字：單字從上方落下；已打的字變淡，目前要打的字加底線 */
  .drop-ground{position:absolute;left:0;right:0;bottom:0;height:16%;background:linear-gradient(#5B6B8C,#3D4A66);}
  .drop-ship{
    position:absolute;left:50%;bottom:9%;z-index:2;font-size:34px;line-height:1;
    transform:translateX(-50%);transition:transform .12s ease;
  }
  .drop-ship.fire{transform:translateX(-50%) translateY(-8px) scale(1.15);}
  .drop-word{
    position:absolute;top:-44px;z-index:3;transform:translateX(-50%);
    display:flex;align-items:center;gap:6px;white-space:nowrap;
    padding:4px 14px 4px 10px;border-radius:999px;background:rgba(255,255,255,.96);color:var(--ink);
    font-family:var(--font-display);font-weight:800;font-size:clamp(20px,3.2vw,28px);letter-spacing:.08em;
    box-shadow:0 4px 14px rgba(0,0,0,.4);
  }
  .drop-word .dc{display:inline-block;border-bottom:3px solid transparent;transition:color .12s ease;}
  .drop-word .dc.done{color:var(--good);opacity:.55;}
  .drop-word .dc.cur{color:var(--accent);border-bottom-color:var(--accent);}
  .drop-word.boom{background:#FFD9D9;animation:drop-boom .45s ease forwards;}
  .drop-word.wshake{animation:drop-shake .22s ease;}
  @keyframes drop-boom{to{opacity:0;transform:translateX(-50%) scale(1.25);}}
  @keyframes drop-shake{0%,100%{transform:translateX(-50%);}25%{transform:translateX(calc(-50% - 5px));}75%{transform:translateX(calc(-50% + 5px));}}

  /* ---------- Keyboard tray ---------- */
  .keyboard-tray {
    position: relative;
    background: var(--tray);
    border-radius: 24px; /* 圓角加大更現代 */
    padding: clamp(16px, 3vh, 24px) clamp(12px, 2vw, 20px);
    /* 超輕柔的陰影，捨棄 inset 內陰影 */
    box-shadow: 0 12px 36px -12px rgba(0, 0, 0, 0.06); 
    overflow-x: auto;
    width: 100%;
    max-width: 900px;
    margin: 0 auto; 
  }

  .key {
    position: relative;
    flex: 1;
    min-width: 0;
    height: clamp(34px, 7vh, 48px); /* 稍微增高按鍵 */
    border-radius: 8px; /* 柔和的按鍵圓角 */
    background: var(--key-face);
    /* 將邊框與陰影變淺，達到扁平化效果 */
    border: 1px solid #F1F2F6;
    box-shadow: 0 2px 4px rgba(0,0,0,0.03);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: clamp(11px, 1.5vw, 16px);
    color: var(--key-text);
    user-select: none;
    overflow: hidden;
    white-space: nowrap;
    padding: 0 2px;
    cursor: pointer;
    transition: all 0.12s ease;
  }

  .key.pressed {
    transform: translateY(2px);
    box-shadow: none;
    background: #F8F9FA;
  }
  .keyboard-tray.ended{opacity:.5;filter:grayscale(.3);}

  /* ---------- Pre-round countdown（改為在左上角泡泡內顯示，不再遮住整個鍵盤） ---------- */
  .key-pill.pop{animation:countdownPop .35s ease;}
  @keyframes countdownPop{
    0%{transform:scale(.7);opacity:.3;}
    60%{transform:scale(1.08);opacity:1;}
    100%{transform:scale(1);opacity:1;}
  }
  .keyboard{
    display:flex;
    flex-direction:column;
    gap:clamp(4px,1vh,8px);
    width:100%;
    min-width:340px;
  }
  .row{display:flex;gap:clamp(3px,0.8vw,8px);}
  .key{
    position:relative;
    flex:1;
    min-width:0;
    height:clamp(30px,6.4vh,44px);
    border-radius:9px;
    background:var(--key-face);
    border:1px solid var(--key-edge);
    box-shadow:0 2px 0 var(--key-edge);
    display:flex;
    align-items:center;
    justify-content:center;
    font-family:var(--font-display);
    font-weight:600;
    font-size:clamp(9px,1.5vw,14px);
    color:var(--key-text);
    user-select:none;
    overflow:hidden;
    white-space:nowrap;
    padding:0 2px;
    cursor:pointer;
    touch-action:manipulation;
    transition:background .12s ease, box-shadow .08s ease, transform .08s ease, border-color .12s ease;
  }
  .key.special{font-size:clamp(7.5px,1.15vw,11px);font-weight:500;color:var(--ink-soft);}
  .key .win-icon{
    width:1.15em;
    height:1.15em;
    fill:currentColor;
    display:block;
  }

  /* 【修改】鍵帽的三層內容(字母／注音／符號)各自獨立開關,預設都先隱藏，
     由 .keyboard 上的 show-letter / show-zhuyin / show-symbol class 決定要不要顯示 */
  .key .key-main-label{display:none;}
  .key .zhuyin-label{display:none;}
  .keyboard.show-letter .key .key-main-label{display:block;}
  .keyboard.show-zhuyin .key .zhuyin-label{display:block;}
  /* Shift／Ctrl／Alt／Backspace 等功能鍵的文字不受「鍵帽加字母」開關影響，一律顯示 */
  .keyboard .key.special .key-main-label{display:block !important;}

  /* 鍵帽右上角符號角標(如「1」鍵旁的「!」)，獨立由「鍵帽加符號」開關控制，不佔用主要排版空間 */
  .key .shift-label{
    display:none;
    position:absolute;
    top:2px;
    right:4px;
    font-size:clamp(6.5px,1vw,9px);
    line-height:1;
    color:var(--ink-soft);
    font-weight:500;
    pointer-events:none;
  }
  .keyboard.show-symbol .key.has-shift .shift-label{display:block;}

  /* 字母與注音同時顯示時，改成上下堆疊排版，避免互相重疊 */
  .keyboard.show-letter.show-zhuyin .key{flex-direction:column;justify-content:center;gap:1px;}
  /* 英打課程(預設)：字母為主、注音縮小當輔助 */
  .keyboard.show-letter.show-zhuyin:not(.zhuyin-emphasis) .key .zhuyin-label{
    font-size:clamp(7px,1.1vw,10px);
    line-height:1;
    color:var(--ink-soft);
    font-weight:500;
  }
  .keyboard.show-letter.show-zhuyin:not(.zhuyin-emphasis) .key .key-main-label{font-size:.82em;line-height:1;}
  /* 注音課程：注音為主、字母縮小當輔助參考 */
  .keyboard.show-letter.show-zhuyin.zhuyin-emphasis .key .zhuyin-label{
    font-size:clamp(10px,1.6vw,15px);
    line-height:1;
    color:var(--key-text);
    font-weight:700;
  }
  .keyboard.show-letter.show-zhuyin.zhuyin-emphasis .key .key-main-label{
    font-size:clamp(7px,1vw,10px);
    line-height:1;
    color:var(--ink-soft);
    font-weight:500;
  }

  .physical-key-hint{
    color:var(--ink-soft);
    font-size:13px;
    margin-left:4px;
  }

  /* finger colour hint (toggleable) */
  .keyboard.show-fingers .key[data-finger]{
    background:color-mix(in srgb, var(--finger-color) 16%, white);
    border-color:color-mix(in srgb, var(--finger-color) 55%, white);
  }
  /* 【新增】指法顏色「鮮明」模式：色彩比例從 16%/55% 加深到 34%/70%，讓不同手指的顏色差異更好分辨 */
  .keyboard.show-fingers.vivid-fingers .key[data-finger]{
    background:color-mix(in srgb, var(--finger-color) 34%, white);
    border-color:color-mix(in srgb, var(--finger-color) 70%, white);
  }

  .key.bump::after{
    content:"";
    position:absolute;
    bottom:6px;
    width:14px;height:3px;
    border-radius:2px;
    background:var(--ink-soft);
    opacity:.55;
  }

  .key.pressed{
    transform:translateY(2px);
    box-shadow:none;
  }
  .key.target{
    background:var(--accent-soft) !important;
    border-color:var(--accent) !important;
    color:var(--accent);
    box-shadow:0 2px 0 var(--accent), 0 0 0 3px rgba(46,109,164,.18);
  }
  .key.correct{
    background:var(--good-soft) !important;
    border-color:var(--good) !important;
    color:var(--good);
    transform:translateY(2px);
    box-shadow:none;
  }
  .key.wrong{
    background:var(--bad-soft) !important;
    border-color:var(--bad) !important;
    color:var(--bad);
  }

  footer.note{
    text-align:center;
    font-size:12px;
    color:var(--ink-soft);
    padding-top:6px;
  }

  /* ---------- 【新增】課程首頁（Home view）：卡片方格式的課程地圖，取代原本只能靠下拉清單選課 ---------- */
  /* 設計參考 TypingClub 首頁：大課程分頁 → 進度摘要列 → 依 group 分區的卡片方格，
     每張卡片＝一小課，完成過的右上角打勾、底部顯示最佳成績；不鎖定未完成課程，任何一張都能直接點進去 */
  .home-view{
    display:flex;
    flex-direction:column;
    gap:16px;
  }
  /* 【修改】主課程（大課程）選單原本用 .home-topbar 包在課程首頁內容裡自成一列，
     現在移到最外層 .topbar 跟主標題同一列、同高度，這裡改成推到 .topbar 最右邊 */
  .home-course-select{
    min-width:140px;
    margin-left:auto;
  }
  /* 【刪除】原本的 .home-bar／.home-bar-stats／.home-bar-track／.home-bar-fill（完成度進度表）整組拿掉：
     不再於課程首頁顯示整體完成度百分比與進度條 */
  /* 【新增】每個分組（首排 Home Row／首排＋下排／三排全字母…）獨立成一個區塊，
     讓 #homeGroups 用 gap 統一控制「組與組之間」的間距，跟組內「標題到卡片」的間距分開處理 */
  #homeGroups{
    display:flex;
    flex-direction:column;
    gap:28px;
  }
  .home-group-title{
    font-family:var(--font-display);
    font-weight:700;
    font-size:18px;
    color:var(--ink);
    padding:0 2px 10px;
  }
  /* 卡片方格：最小 132px 自動換行，畫面寬就多排幾張、窄就自動折行 */
  .home-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(132px, 1fr));
    gap:12px;
  }
  .lesson-card{
    position:relative;
    display:flex;
    flex-direction:column;
    align-items:stretch;
    gap:6px;
    background:var(--key-face);
    border:1px solid var(--key-edge);
    border-radius:14px;
    padding:10px 10px 0;
    cursor:pointer;
    text-align:left;
    font-family:var(--font-body);
    color:var(--ink);
    box-shadow:0 10px 22px -18px rgba(35,50,65,.5);
    transition:transform .12s ease, box-shadow .15s ease, border-color .15s ease;
  }
  .lesson-card:hover{
    transform:translateY(-2px);
    border-color:var(--accent);
    box-shadow:0 16px 28px -18px rgba(35,50,65,.55);
  }
  .lesson-card:active{transform:translateY(0);}
  .lesson-card.done{background:var(--good-soft);border-color:#B7E3CC;}
  .lesson-card.current{border:2px solid var(--accent);padding:9px 9px 0;}
  .lesson-card-num{
    font-family:var(--font-display);
    font-weight:700;
    font-size:20px;
    color:var(--ink-soft);
    line-height:1;
  }
  .lesson-card.done .lesson-card-num{color:var(--good);}
  .lesson-card-check{
    position:absolute;
    top:8px;right:8px;
    width:22px;height:22px;
    border-radius:50%;
    background:var(--good);
    color:#fff;
    font-size:13px;
    font-weight:700;
    display:flex;
    align-items:center;
    justify-content:center;
    line-height:1;
  }
  .lesson-card-visual{
    height:56px;
    display:flex;
    align-items:center;
    justify-content:center;
    font-family:var(--font-display);
    font-weight:700;
    color:var(--accent);
  }
  .lesson-card-visual.keys{font-size:28px;letter-spacing:.06em;}
  .lesson-card-visual.emoji{font-size:32px;}
  .lesson-card-name{
    font-size:12.5px;
    font-weight:600;
    line-height:1.35;
    color:var(--ink);
    border-top:1px solid var(--key-edge);
    padding:8px 0;
    min-height:46px;
  }
  .lesson-card.done .lesson-card-name{border-top-color:#B7E3CC;}
  .lesson-card-meta{
    position:absolute;
    bottom:6px;right:10px;
    font-size:10.5px;
    color:var(--good);
    font-weight:600;
  }
  /* 【修改】原本放提示文字的地方（已移除），現在放「重設進度」按鈕，置中在課程首頁最下面 */
  .home-footer{
    display:flex;
    justify-content:center;
    padding-top:8px;
  }
  /* 【新增】下拉清單裡的完成勾勾，跟課程首頁的卡片狀態同步 */
  .lesson-dropdown-item{display:flex;align-items:center;gap:6px;}
  .lesson-dropdown-item .item-check{color:var(--good);font-weight:700;flex:none;}
  .lesson-dropdown-item.selected .item-check{color:#fff;}

  /* ---------- 【新增】打字紀錄頁面（History view） ---------- */
  .history-view{
    display:flex;
    flex-direction:column;
    gap:14px;
  }
  .history-view-header{
    display:flex;
    align-items:center;
    justify-content:space-between;
    flex-wrap:wrap;
    gap:10px;
    padding:2px 2px 0;
  }
  .history-view-title{
    font-family:var(--font-display);
    font-weight:700;
    font-size:19px;
    color:var(--ink);
    display:flex;
    align-items:center;
    gap:8px;
  }
  .history-count-badge{
    font-family:var(--font-body);
    font-weight:600;
    font-size:12px;
    color:var(--accent);
    background:var(--accent-soft);
    border-radius:20px;
    padding:2px 10px;
  }
  /* 【刪除】.history-view-actions：原本用來橫向排列「提示文字＋清除紀錄＋返回練習」三個元素，
     現在標題列只剩「返回練習」一顆按鈕，直接靠 .history-view-header 的 justify-content:space-between 排版即可 */
  /* 【修改】提示文字從標題列移到清單最下面，改置中對齊，樣式跟著調整 */
  .history-view-hint{
    font-size:12px;
    color:var(--ink-soft);
    text-align:center;
    padding-top:4px;
  }
  .history-empty{
    display:none;
    flex-direction:column;
    align-items:center;
    gap:8px;
    text-align:center;
    color:var(--ink-soft);
    font-size:14px;
    background:var(--tray);
    border-radius:16px;
    padding:48px 20px;
    box-shadow:0 14px 30px -20px rgba(35,50,65,.3), 0 2px 0 rgba(255,255,255,.6) inset;
  }
  .history-empty.show{display:flex;}
  .history-empty-emoji{font-size:34px;}
  .history-list{
    display:flex;
    flex-direction:column;
    gap:12px;
  }
  .history-card{
    background:var(--tray);
    border-radius:16px;
    padding:14px 18px;
    box-shadow:0 14px 30px -20px rgba(35,50,65,.3), 0 2px 0 rgba(255,255,255,.6) inset;
    display:flex;
    flex-direction:column;
    gap:10px;
  }
  .history-card-top{
    display:flex;
    align-items:center;
    justify-content:space-between;
    flex-wrap:wrap;
    gap:8px;
  }
  .history-card-lesson{
    display:flex;
    align-items:center;
    gap:8px;
    font-family:var(--font-display);
    font-weight:700;
    font-size:15px;
    color:var(--ink);
  }
  .history-course-icon{
    font-size:13px;
    font-weight:600;
    color:var(--accent);
    background:var(--accent-soft);
    border-radius:8px;
    padding:2px 8px;
    flex:none;
  }
  .history-card-time{
    font-size:12px;
    color:var(--ink-soft);
    white-space:nowrap;
  }
  .history-card-stats{
    display:flex;
    flex-wrap:wrap;
    gap:10px 18px;
  }
  .history-stat{
    display:flex;
    align-items:center;
    gap:6px;
    font-size:13px;
    color:var(--ink-soft);
  }
  .history-stat .icon{font-size:15px;line-height:1;}
  .history-stat .val{
    font-family:var(--font-display);
    font-weight:700;
    font-size:14px;
    color:var(--ink);
  }
  .history-stat.acc .val{color:var(--accent);}
  .history-stat.ok .val{color:var(--good);}
  .history-stat.bad .val{color:var(--bad);}
  .history-stat.streak .val{color:#C9852F;}
  .history-card:first-child{border:1px solid var(--accent-soft);}
  /* 【修改】吉祥物泡泡裡「時間到」的結算：改成分格網格（每格＝小標籤在上、大數值在下），
     不再跟打字紀錄卡片共用一列到底的 .history-stat，避免 6 項數據擠成一行顯得雜亂 */
  .result-title{
    font-family:var(--font-display);
    font-weight:700;
    font-size:14px;
    color:var(--ink-soft);
    margin-bottom:12px;
  }
  /* 【修改】原本 3欄×2列 的方格改成「單一橫條」：預設 6 欄一列，靠 grid-gap 當作分隔線；
     置中對齊＋加上 .result-icon 圖示，視覺更輕薄、也更符合「6 項平行摘要數據」的語意 */
  .result-grid{
    display:grid;
    grid-template-columns:repeat(6, minmax(0,1fr));
    gap:1px;
    background:#E5EDF5;
    border:1px solid #E5EDF5;
    border-radius:12px;
    overflow:hidden;
  }
  .result-cell{
    background:#FBFDFF;
    padding:10px 8px;
    display:flex;
    flex-direction:column;
    align-items:center;
    text-align:center;
    gap:3px;
    min-width:0;
  }
  .result-label{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    gap:4px;
    font-size:12px;
    color:var(--ink-soft);
    line-height:1.2;
    white-space:nowrap;
  }
  /* 【新增】每個統計項目前面的小圖示（🏆🎯⚡✅❌🔥），跟文字標籤放同一行 */
  .result-icon{
    font-size:13px;
    line-height:1;
  }
  .result-value{
    font-family:var(--font-display);
    font-weight:700;
    font-size:20px;
    line-height:1.1;
    color:var(--ink);
    word-break:break-all;
  }
  .result-value.small{font-size:14px;}
  .result-value.acc{color:var(--accent);}
  .result-value.ok{color:var(--good);}
  .result-value.bad{color:var(--bad);}
  .result-value.streak{color:#C9852F;}
  .result-unit{font-size:11px;color:var(--ink-soft);line-height:1;}
  .result-cell.hero{background:rgba(207,230,250,.45);}
  .result-cell.hero .result-value{font-size:24px;color:var(--accent);}
  .result-foot{
    margin-top:12px;
    display:flex;
    flex-wrap:wrap;
    align-items:center;
    gap:10px;
  }
  .result-foot #mistakesLine{font-size:13px;color:var(--ink-soft);flex:1 1 180px;}
  .result-foot #gameResultLine{font-size:13px;font-weight:700;color:var(--ink);flex:1 1 100%;} /* 【新增】小遊戲結算訊息獨佔一行，放在錯鍵統計旁 */
  /* 【修改】響應式斷點：中螢幕先收成 3 欄（維持 2 列），窄螢幕再收成 2 欄，避免 6 項擠成一排看不清楚 */
  @media (max-width:760px){
    .result-grid{grid-template-columns:repeat(3, minmax(0,1fr));}
  }
  @media (max-width:420px){
    .result-grid{grid-template-columns:repeat(2, minmax(0,1fr));}
    .result-value{font-size:18px;}
  }
  /* 【新增】正確率旁邊的樣本數標註（例如「(共12次)」），讓使用者自行判斷這個百分比的參考價值 */
  .sample-note{
    font-family:var(--font-body);
    font-weight:500;
    font-size:11px;
    color:var(--ink-soft);
    margin-left:2px;
  }

  .stat.time{
    position:relative;
    cursor:pointer;
    border-radius:8px;
    padding:2px 6px;
    margin:-2px -6px;
    transition:background .12s ease;
  }
  .stat.time:hover{background:var(--accent-soft);}
  .time-menu{
    position:absolute;
    top:calc(100% + 8px);
    left:0;
    background:#fff;
    border:1px solid var(--accent-soft);
    border-radius:12px;
    box-shadow:0 16px 34px -16px rgba(35,50,65,.4);
    padding:6px;
    display:none;
    flex-direction:column;
    min-width:118px;
    z-index:15;
  }
  .time-menu.open{display:flex;}
  .time-menu-item{
    font-family:var(--font-body);
    font-size:13px;
    font-weight:500;
    color:var(--ink);
    padding:7px 12px;
    border-radius:7px;
    cursor:pointer;
    white-space:nowrap;
    transition:background .12s ease;
  }
  .time-menu-item:hover{background:var(--accent-soft);color:var(--accent);}
  .time-menu-item.selected{background:var(--accent);color:#fff;}

  @media (max-width:600px){
    .stats{gap:14px;font-size:14px;}
    .brand{font-size:19px;}
    .bubble{font-size:14px;padding:12px 14px;}
  }
