/* ===== 學庫 HOKU 模擬考試系統 — design tokens（Gemini 啟發 ・ aurora 藍紫冷色系） ===== */
:root{
  /* ===== 設計系統 v2：Playful yet Professional（EdTech） =====
     變數名保持不變（全站 class 沿用），只換數值 → 一次換膚。 */
  --bg:#F8FAFC;               /* Canvas：Soft Porcelain */
  --bg-top:#F8FAFC;           /* 頁面頂部同色（扁平） */
  --surface:#F1F5F9;          /* 淺面板 slate-100 */
  --card:#FFFFFF;             /* 卡面純白 */
  --card-border:rgba(226,232,240,.9);
  --card-radius:16px;         /* rounded-2xl */
  --card-shadow:0 1px 2px rgba(15,23,42,.04), 0 6px 16px rgba(15,23,42,.05);
  --card-shadow-lift:0 4px 10px rgba(15,23,42,.06), 0 12px 28px rgba(15,23,42,.08);

  --brand:#2A5CE8;            /* Electric Royal Blue */
  --brand-dark:#1E46B8;
  --brand-soft:#EEF3FE;
  --gold:#FFB800;             /* Sunlight Gold */
  --gold-dark:#C98F00;
  --gold-soft:#FFF6E0;
  --mint:#10B981;             /* Vibrant Mint */
  --mint-dark:#0B8F63;
  --mint-soft:#E7F8F1;
  --coral:#F43F5E;            /* Coral Punch */
  --coral-dark:#C42D48;
  --coral-soft:#FEECEF;
  --slate-150:#E9EEF5;

  --primary:#2A5CE8;
  --primary-dark:#1E46B8;
  --cyan:#3B82F6;
  --periwinkle:#6D8CF0;
  --purple:#6D8CF0;
  --aurora:linear-gradient(135deg,#2A5CE8 0%,#3B6FF5 100%);
  --aurora-wide:linear-gradient(120deg,#2A5CE8 0%,#3B6FF5 55%,#6D8CF0 100%);
  --olive:#2A5CE8;            /* 連結／標題點綴（沿用舊名） */
  --terracotta:#2A5CE8;       /* 次要強調（沿用舊名） */
  --blush:#EEF3FE;            /* soft 按鈕底 */
  --sage:#2A5CE8;
  --mustard:#FFB800;
  --bronze:#C2761E;           /* 等級徽章 */
  --silver:#94A3B8;
  --diamond:#2A5CE8;
  --ink:#0F172A;              /* Deep Ink Navy */
  --ink-soft:#475569;         /* Slate Gray */
  --line:#E2E8F0;
  --ok:#10B981;
  --bad:#F43F5E;
  --warn:#FFB800;
  --radius-pill:999px;
}

*{box-sizing:border-box;}
html,body{margin:0;padding:0;}
body{
  /* 純扁平 Canvas（設計系統 v2）：睇長都唔攰，卡同底清楚分離 */
  background:var(--bg);
  color:var(--ink);
  /* 拉丁字母／數字用 Nunito（圓潤），中文 fallback 去 Noto Sans TC */
  font-family:'Nunito','Plus Jakarta Sans','Noto Sans TC',system-ui,-apple-system,sans-serif;
  font-weight:700;
  font-size:16px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
}
#app{max-width:960px;margin:0 auto;padding:20px 16px 92px;}
/* owner 控制台：用盡闊頁面（app.js 喺渲染 owner-home 時加 .page-owner 落 body） */
body.page-owner #app{max-width:1640px;padding:16px 22px 60px;}
h1,h2,h3,h4{font-weight:700;line-height:1.4;margin:0 0 12px;}
h1{font-size:26px;} h2{font-size:21px;} h3{font-size:18px;}
a{color:var(--olive);text-decoration:none;}
a:hover{text-decoration:underline;}
.muted{color:var(--ink-soft);}
.small{font-size:13px;}
.center{text-align:center;}
.mt{margin-top:16px;} .mb{margin-bottom:16px;}
pre{white-space:pre-wrap;font-family:inherit;}

/* ===== 卡片（白底 + 淺灰邊框 + 柔和陰影） ===== */
.card{
  background:var(--card);
  border:1px solid var(--card-border);
  border-radius:var(--card-radius);
  box-shadow:var(--card-shadow);
  padding:26px;
  margin-bottom:20px;
}

/* ===== 按鈕（pill 形，主掣 aurora 藍青漸變；小學生用偏大） ===== */
/* ===== 按鈕：立體下壓（tactile 3D push-button）===== */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  font-family:inherit;font-size:16px;font-weight:800;
  border:none;cursor:pointer;border-radius:var(--radius-pill);
  padding:13px 26px;background:var(--brand);color:#fff;
  box-shadow:0 4px 0 0 var(--brand-dark);
  transition:transform .06s ease, box-shadow .06s ease, background .15s ease;
  text-decoration:none;
}
.btn:hover{background:var(--primary-dark);text-decoration:none;}
.btn:active{transform:translateY(4px);box-shadow:0 0 0 0 var(--brand-dark);}
.btn:disabled{background:var(--slate-150);color:#94A3B8;box-shadow:none;cursor:not-allowed;transform:none;}
.btn-sage{background:var(--brand);box-shadow:0 4px 0 0 var(--brand-dark);}
.btn-sage:active{box-shadow:0 0 0 0 var(--brand-dark);}
.btn-blue{background:var(--brand);box-shadow:0 4px 0 0 var(--brand-dark);}
.btn-blue:active{box-shadow:0 0 0 0 var(--brand-dark);}
.btn-mustard{background:var(--gold);color:#4A2E00;box-shadow:0 4px 0 0 var(--gold-dark);}
.btn-mustard:hover{background:#F5AE00;}
.btn-mustard:active{box-shadow:0 0 0 0 var(--gold-dark);}
.btn-mint{background:var(--mint);box-shadow:0 4px 0 0 var(--mint-dark);}
.btn-mint:active{box-shadow:0 0 0 0 var(--mint-dark);}
.btn-coral{background:var(--coral);box-shadow:0 4px 0 0 var(--coral-dark);}
.btn-coral:active{box-shadow:0 0 0 0 var(--coral-dark);}
.btn-ghost{background:#fff;color:var(--ink-soft);border:1px solid var(--line);box-shadow:0 4px 0 0 var(--line);}
.btn-ghost:hover{background:#fff;border-color:#CBD5E1;}
.btn-ghost:active{transform:translateY(4px);box-shadow:0 0 0 0 var(--line);}
.btn-soft{background:var(--brand-soft);color:var(--brand);box-shadow:0 4px 0 0 #D8E3FB;}
.btn-soft:hover{background:var(--brand-soft);}
.btn-soft:active{transform:translateY(4px);box-shadow:0 0 0 0 #D8E3FB;}
.btn-sm{padding:9px 16px;font-size:14px;}
.btn-lg{padding:15px 32px;font-size:18px;}
.btn-block{width:100%;}

/* ===== 表單 ===== */
.field{margin-bottom:18px;}
.field label{display:block;font-weight:500;margin-bottom:6px;}
.input, .field input[type=text], .field input[type=password],
.field input[type=number], .field select, .field textarea{
  width:100%;font-family:inherit;font-size:16px;color:var(--ink);
  padding:12px 16px;border:1.5px solid var(--line);border-radius:16px;
  background:var(--card);outline:none;transition:border-color .15s;
}
.input:focus, .field input:focus, .field select:focus, .field textarea:focus{border-color:var(--primary);}
.field textarea{min-height:110px;resize:vertical;}

/* ===== Tab（pill 容器式） ===== */
.tabs{
  display:inline-flex;gap:6px;flex-wrap:wrap;
  background:var(--surface);border-radius:var(--radius-pill);
  padding:5px;margin-bottom:22px;
}
.tab{
  font-family:inherit;font-size:16px;font-weight:500;cursor:pointer;
  background:transparent;border:none;color:var(--ink-soft);
  padding:9px 20px;border-radius:var(--radius-pill);
  transition:background .15s ease, color .15s ease;
}
.tab:hover{color:var(--ink);}
.tab.active{background:var(--card);color:var(--olive);font-weight:700;box-shadow:0 1px 3px rgba(60,64,67,.10);}
.tabs-sub{margin-top:-10px;margin-bottom:18px;}
.tabs-sub .tab{font-size:14.5px;padding:6px 16px;}

/* ===== Header（頂部個人資料卡） ===== */
.app-header{
  display:flex;align-items:center;gap:18px;flex-wrap:wrap;
  background:var(--card);border-radius:var(--card-radius);
  box-shadow:var(--card-shadow);padding:18px 24px;margin-bottom:22px;
}
.header-avatar{
  width:64px;height:64px;border-radius:50%;overflow:hidden;flex:none;
  background:var(--surface);display:flex;align-items:center;justify-content:center;
}
.header-avatar img{width:100%;height:100%;object-fit:cover;}
.header-info{flex:1;min-width:200px;}
.header-name-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
.header-name{font-size:20px;font-weight:700;}
.badge{
  font-size:12.5px;font-weight:700;color:#fff;border-radius:var(--radius-pill);
  padding:3px 12px;letter-spacing:.5px;
}
.badge-bronze{background:var(--bronze);}
.badge-silver{background:var(--silver);}
.badge-gold{background:var(--gold);}
.badge-diamond{background:var(--diamond);}
.header-motto{color:var(--ink-soft);font-size:14px;margin-top:2px;}
.progress{height:8px;background:var(--surface);border-radius:99px;overflow:hidden;margin-top:8px;max-width:280px;}
.progress > i{display:block;height:100%;background:var(--aurora);border-radius:99px;transition:width .4s;}
.progress-label{font-size:12px;color:var(--ink-soft);margin-top:3px;}
.header-actions{display:flex;align-items:center;gap:14px;margin-left:auto;}

/* 通知鈴 */
.bell{position:relative;background:none;border:none;cursor:pointer;font-size:24px;line-height:1;padding:6px;}
.bell-dot{
  position:absolute;top:2px;right:2px;width:11px;height:11px;border-radius:50%;
  background:#D93025;border:2px solid var(--card);
}
.notif-panel{
  position:absolute;top:calc(100% + 10px);right:0;z-index:60;width:320px;max-height:400px;overflow:auto;
  background:var(--card);border-radius:20px;box-shadow:var(--card-shadow-lift);padding:8px;
}
.notif-item{padding:10px 12px;border-radius:12px;border-bottom:1px solid var(--line);}
.notif-item:last-child{border-bottom:none;}
.notif-item.unread{background:#EDF3FD;}
.notif-item .notif-text{font-size:14.5px;}
.notif-item .notif-meta{display:flex;justify-content:space-between;align-items:center;margin-top:4px;}
.notif-item .notif-link{font-size:13px;color:var(--olive);cursor:pointer;background:none;border:none;padding:0;font-family:inherit;}
.notif-item .notif-link:hover{text-decoration:underline;}
.bell-wrap{position:relative;}

/* ===== 四科卡（pastel 暖色系） ===== */
.subject-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px;}
.subject-card{
  border:none;cursor:pointer;border-radius:var(--card-radius);padding:26px 18px;
  font-family:inherit;text-align:center;box-shadow:var(--card-shadow);
  transition:transform .12s ease, box-shadow .15s ease;color:var(--ink);
}
.subject-card:hover{transform:translateY(-3px);box-shadow:var(--card-shadow-lift);}
.subject-card .sub-icon{font-size:34px;}
.subject-card .sub-name{font-size:19px;font-weight:700;margin-top:8px;}
.sub-chinese{background:#E8F0FE;}  /* pastel terracotta */
.sub-english{background:#E8F0FE;}  /* pastel sage */
.sub-maths{background:#E1F5FE;}    /* pastel oatmeal-gold */
.sub-gs{background:#F3E8FD;}       /* pastel dusty rose */
.grade-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(90px,1fr));gap:12px;margin-top:14px;}
.grade-btn{
  font-family:inherit;font-size:17px;font-weight:700;cursor:pointer;
  border:1.5px solid var(--line);background:var(--card);color:var(--ink);
  border-radius:var(--radius-pill);padding:12px 0;
  transition:border-color .15s, color .15s, background .15s;
}
.grade-btn:hover{border-color:var(--primary);color:var(--olive);}
.grade-btn.active{border-color:var(--primary);background:var(--primary);color:#fff;}

/* ===== 出題模式卡（快速練習 / 30 分鐘 / 完整） ===== */
.mode-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin-top:12px;}
.mode-card{
  font-family:inherit;cursor:pointer;text-align:left;color:var(--ink);
  border:1.5px solid var(--line);background:var(--card);
  border-radius:22px;padding:18px 20px;box-shadow:var(--card-shadow);
  transition:border-color .15s, background .15s, transform .12s ease, box-shadow .15s ease;
}
.mode-card:hover{transform:translateY(-2px);border-color:var(--primary);box-shadow:var(--card-shadow-lift);}
.mode-card.active{border-color:var(--primary);background:#E8F0FE;box-shadow:0 0 0 1.5px var(--primary) inset;}
.mode-icon{font-size:26px;}
.mode-name{font-size:17px;font-weight:700;margin-top:6px;}
.mode-desc{font-size:13.5px;color:var(--ink-soft);margin-top:3px;line-height:1.55;}
.count-row{display:flex;gap:12px;flex-wrap:wrap;margin-top:10px;}
.count-btn{
  font-family:inherit;font-size:16.5px;font-weight:700;cursor:pointer;color:var(--ink);
  border:1.5px solid var(--line);background:var(--card);
  border-radius:var(--radius-pill);padding:10px 24px;text-align:center;
  transition:border-color .15s, background .15s, color .15s;
}
.count-btn:hover{border-color:var(--primary);}
.count-btn.active{border-color:var(--primary);background:var(--primary);color:#fff;}
.count-time{font-size:12px;font-weight:400;color:var(--ink-soft);margin-top:1px;}
.count-btn.active .count-time{color:rgba(255,255,255,.85);}

/* ===== 列表 / 表格 ===== */
.list-row{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding:14px 6px;border-bottom:1px solid var(--line);
}
.list-row:last-child{border-bottom:none;}
table.table{width:100%;border-collapse:collapse;font-size:15.5px;}
table.table th{text-align:left;color:var(--ink-soft);font-weight:500;padding:10px 12px;border-bottom:2px solid var(--line);}
table.table td{padding:12px;border-bottom:1px solid var(--line);}
table.table tbody tr:hover{background:#F0F4F9;}

/* ===== 橫額 / 提示 ===== */
.banner{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  background:#E8F0FE;border:1.5px solid #D2E3FC;border-radius:20px;
  padding:14px 18px;margin-bottom:18px;
}
.banner .banner-text{flex:1;min-width:200px;}
/* fallback 黃色提示條（範例卷頂替時顯示） */
.banner-warn{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  background:#FEF7E0;border:1.5px solid #F9AB00;color:#B26A00;
  border-radius:16px;padding:12px 16px;margin-bottom:16px;
  font-size:14.5px;font-weight:500;
}
.pill{display:inline-block;font-size:13px;font-weight:700;border-radius:var(--radius-pill);padding:2px 12px;}
.pill-pending{background:#FEF7E0;color:#B26A00;}
.pill-done{background:#E6F4EA;color:#1E8E3E;}
.pill-info{background:#E8F0FE;color:#3367D6;}

/* ===== 倒數計時器 ===== */
.exam-timer{
  position:fixed;top:16px;right:16px;z-index:80;
  background:var(--card);border-radius:var(--radius-pill);
  box-shadow:var(--card-shadow-lift);
  padding:10px 22px;font-size:20px;font-weight:700;color:var(--ink);
  font-variant-numeric:tabular-nums;
}
.exam-timer.warn{color:#fff;background:var(--warn);animation:timerPulse 1.2s infinite;}
@keyframes timerPulse{0%,100%{transform:scale(1);}50%{transform:scale(1.05);}}

/* ===== Toast ===== */
#toast-root{position:fixed;left:50%;bottom:32px;transform:translateX(-50%);z-index:200;display:flex;flex-direction:column;gap:10px;align-items:center;}
.toast{
  background:var(--ink);color:#F0F4F9;border-radius:var(--radius-pill);
  padding:12px 26px;font-size:15.5px;box-shadow:0 6px 20px rgba(60,64,67,.28);
  animation:toastIn .25s ease;max-width:86vw;text-align:center;
}
.toast-error{background:#D93025;}
.toast-success{background:#1E8E3E;}
.toast.out{opacity:0;transition:opacity .3s;}
@keyframes toastIn{from{opacity:0;transform:translateY(12px);}to{opacity:1;transform:none;}}

/* ===== 分數三格輸入組件 ===== */
.frac-input{display:inline-flex;align-items:center;gap:8px;vertical-align:middle;}
.frac-input input{
  width:62px;text-align:center;font-family:inherit;font-size:18px;color:var(--ink);
  padding:9px 6px;border:1.5px solid var(--line);border-radius:12px;background:var(--card);outline:none;
}
.frac-input input:focus{border-color:var(--primary);}
.frac-whole{width:56px;}
.frac-stack{display:inline-flex;flex-direction:column;align-items:center;}
.frac-stack input{width:62px;}
.frac-line{width:66px;height:2.5px;background:var(--ink);border-radius:2px;margin:4px 0;}
.frac-input.frac-readonly input{background:var(--surface);color:var(--ink-soft);}

/* ===== 題目 ===== */
.section-block{margin-bottom:26px;}
.section-head{
  background:var(--brand-soft);border-radius:var(--card-radius);padding:14px 18px;margin-bottom:14px;
}
.section-head .section-title{font-size:17px;font-weight:900;color:var(--brand);}
.section-head .section-marks{color:var(--ink-soft);font-size:14px;margin-left:8px;font-weight:700;}
.section-head .section-instructions{color:var(--ink-soft);font-size:14.5px;margin-top:4px;white-space:pre-line;font-weight:600;}
.question{
  background:var(--card);border:1px solid var(--line);border-radius:var(--card-radius);
  box-shadow:var(--card-shadow);padding:20px;margin-bottom:14px;
}
.q-head{display:flex;gap:10px;align-items:baseline;margin-bottom:8px;}
.q-no{font-weight:900;color:var(--brand);}
.q-marks{margin-left:auto;color:var(--ink-soft);font-size:13.5px;flex:none;font-weight:700;}
.q-passage{
  background:var(--surface);border-left:4px solid var(--gold);border-radius:12px;
  padding:14px 18px;margin:10px 0 14px;white-space:pre-line;font-size:15.5px;
}
.q-prompt{margin:6px 0 12px;font-size:17px;font-weight:800;white-space:pre-line;}
.q-svg{margin:10px 0;overflow-x:auto;}
.q-svg svg.fig, svg.fig{display:block;max-width:100%;height:auto;background:var(--card);border:1px solid var(--line);border-radius:12px;margin:8px 0;padding:6px;}

/* 題目內嵌 HTML（種子卷分數排版、價錢牌、收費表） */
.q-prompt .frac, .ans-ok .frac, .frac{display:inline-flex;flex-direction:column;align-items:center;vertical-align:middle;font-size:.78em;line-height:1.25;margin:0 3px;}
.frac .fn{border-bottom:1.5px solid currentColor;padding:0 5px;}
.frac .fd{padding:0 5px;}
.price-cards{display:flex;gap:18px;flex-wrap:wrap;margin:10px 0;}
.price-card{border:2px solid var(--terracotta);border-radius:16px;background:#F0F4F9;padding:12px 26px;text-align:center;font-size:19px;line-height:1.5;}
.price-card b{font-size:26px;color:var(--terracotta);}
table.fee{border-collapse:collapse;margin:10px 0;background:var(--card);}
table.fee th, table.fee td{border:1.5px solid #3C4043;padding:6px 22px;font-size:16.5px;text-align:center;}
table.fee th{background:#E9EEF6;}
.q-opt{
  display:flex;align-items:center;gap:10px;padding:10px 14px;margin-bottom:8px;
  border:1.5px solid var(--line);border-radius:16px;cursor:pointer;background:var(--card);
  font-size:16px;transition:border-color .15s, background .15s;
}
.q-opt:hover{border-color:var(--primary);}
.q-opt input{accent-color:var(--primary);width:18px;height:18px;flex:none;}
.q-opt.selected{border-color:var(--primary);background:#E8F0FE;}
.q-opt:has(input:checked){border-color:var(--primary);background:#E8F0FE;}
.question input[type=text].q-text{
  width:100%;font-family:inherit;font-size:16px;padding:11px 15px;
  border:1.5px solid var(--line);border-radius:14px;background:var(--card);outline:none;
}
.question input[type=text].q-text:focus{border-color:var(--primary);}
.question textarea.q-textarea{
  width:100%;min-height:120px;font-family:inherit;font-size:16px;padding:12px 15px;
  border:1.5px solid var(--line);border-radius:14px;background:var(--card);outline:none;resize:vertical;
}
.question textarea.q-textarea:focus{border-color:var(--primary);}
.question select.q-select{
  font-family:inherit;font-size:16px;padding:11px 15px;min-width:240px;
  border:1.5px solid var(--line);border-radius:14px;background:var(--card);outline:none;
}

/* 排句（order）題 */
.order-area{
  min-height:56px;border:2px dashed var(--line);border-radius:16px;
  padding:10px;display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:12px;
  background:var(--card);
}
.order-area:empty::before{content:'按順序撳下面嘅字詞加入答案';color:var(--ink-soft);font-size:14px;}
.order-pool{display:flex;flex-wrap:wrap;gap:8px;}
.chip{
  font-family:inherit;font-size:16.5px;cursor:pointer;border-radius:var(--radius-pill);
  border:1.5px solid var(--sage);background:#E8F0FE;color:var(--ink);padding:7px 18px;
}
.chip:hover{background:#D2E3FC;}
.chip .chip-idx{font-size:12px;color:var(--ink-soft);margin-right:5px;}
.order-area .chip{border-color:var(--terracotta);background:#E8F0FE;}
.chip:disabled{cursor:default;opacity:.85;}

/* 多空（blanks）題 */
.blank-slot{display:inline-block;vertical-align:middle;margin:0 2px;}
.question input[type=text].q-text.blank-input{width:auto;min-width:90px;max-width:160px;padding:6px 10px;font-size:15px;}
.question select.q-select.blank-input{min-width:0;padding:6px 10px;font-size:15px;}
.blank-row{display:flex;align-items:center;gap:8px;margin:6px 0;}
.blank-row .blank-no{color:var(--ink-soft);font-size:14px;flex:none;}
.order-area.readonly{border-style:solid;}

/* ===== 結果頁 ===== */
.score-hero{text-align:center;padding:36px 24px;}
.score-big{font-size:52px;font-weight:700;color:var(--olive);line-height:1.1;}
.score-big .score-max{font-size:26px;color:var(--ink-soft);}
.q-result-mark{flex:none;width:34px;height:34px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:700;color:#fff;font-size:17px;}
.q-correct{background:var(--ok);}
.q-wrong{background:var(--bad);}
.ans-line{font-size:15.5px;margin:6px 0;}
.ans-line .ans-label{font-weight:700;color:var(--ink-soft);margin-right:8px;}
.ans-ok{color:var(--ok);font-weight:700;}
.ans-bad{color:var(--bad);font-weight:700;}
.explain-box{
  background:#E8F0FE;border-left:4px solid var(--sage);border-radius:12px;
  padding:12px 16px;margin-top:12px;font-size:15px;white-space:pre-line;
}
.q-foot{display:flex;justify-content:flex-end;margin-top:12px;}

/* ===== 登入 / 註冊 ===== */
.auth-wrap{max-width:460px;margin:48px auto 0;}
.auth-logo{text-align:center;margin-bottom:26px;}
.auth-logo .logo-mark{font-size:44px;}
/* 品牌標記：立體藍方塊 + 書本圖示（設計系統 v2） */
.brand-mark-lg{
  width:58px;height:58px;border-radius:18px;margin:0 auto 14px;
  background:var(--brand);color:#fff;display:grid;place-items:center;
  box-shadow:0 5px 0 0 var(--brand-dark);
}
.brand-mark-lg svg{width:30px;height:30px;}
.auth-logo h1{font-size:26px;font-weight:900;margin:0 0 4px;}
.auth-logo p{color:var(--ink-soft);margin:0;font-size:14.5px;}
.auth-alt{text-align:center;margin-top:16px;font-size:15px;}
.owner-entry{
  display:block;text-align:center;margin:34px auto 0;font-size:13px;color:var(--ink-soft);
  background:none;border:none;cursor:pointer;font-family:inherit;
}
.owner-entry:hover{color:var(--olive);text-decoration:underline;}

/* ===== 全屏載入遮罩（生成卷） ===== */
.loading-mask{
  position:fixed;inset:0;z-index:300;background:rgba(248,249,250,.9);
  display:flex;align-items:center;justify-content:center;padding:20px;
}
.loading-card{
  background:var(--card);border-radius:26px;

  box-shadow:0 8px 34px rgba(60,64,67,.18);
  padding:34px 46px;text-align:center;min-width:270px;
}
.loading-spin{display:flex;gap:12px;justify-content:center;margin-bottom:18px;}
.loading-spin span{
  width:15px;height:15px;border-radius:50%;
  background:linear-gradient(135deg,var(--primary),var(--cyan));
  animation:loadBounce 1s infinite ease-in-out;
}
.loading-spin span:nth-child(2){animation-delay:.16s;background:linear-gradient(135deg,var(--periwinkle),var(--purple));}
.loading-spin span:nth-child(3){animation-delay:.32s;background:linear-gradient(135deg,var(--cyan),var(--periwinkle));}
@keyframes loadBounce{0%,80%,100%{transform:translateY(0);opacity:.45;}40%{transform:translateY(-13px);opacity:1;}}
.loading-title{font-size:17px;font-weight:700;}
.loading-timer{
  font-size:28px;font-weight:700;color:var(--primary);
  margin:8px 0 4px;font-variant-numeric:tabular-nums;
}
.loading-sub{font-size:13.5px;color:var(--ink-soft);}

/* 結果頁卷末 */
.result-foot{display:flex;justify-content:center;margin:28px 0 12px;}

/* ===== Modal ===== */
.modal-mask{
  position:fixed;inset:0;background:rgba(60,64,67,.38);z-index:150;
  display:flex;align-items:center;justify-content:center;padding:20px;
}
.modal{
  background:var(--card);border-radius:28px;box-shadow:0 12px 40px rgba(60,64,67,.25);
  padding:26px;width:100%;max-width:440px;
}
.modal-actions{display:flex;gap:12px;justify-content:flex-end;margin-top:20px;}

/* ===== 雜項 ===== */
.loading-box{text-align:center;color:var(--ink-soft);padding:80px 0;font-size:17px;}
.empty-box{text-align:center;color:var(--ink-soft);padding:34px 0;font-size:15px;}
.exam-submit-bar{position:sticky;bottom:18px;display:flex;justify-content:center;margin-top:26px;}
.divider{height:1px;background:var(--line);margin:20px 0;}
.tag-subject{font-size:13px;font-weight:700;border-radius:var(--radius-pill);padding:2px 12px;background:var(--surface);color:var(--ink);}
.avatar-sm{width:36px;height:36px;border-radius:50%;overflow:hidden;background:var(--surface);display:inline-flex;align-items:center;justify-content:center;flex:none;}
.avatar-sm img{width:100%;height:100%;object-fit:cover;}

/* ===== Profile 頁：頭像選擇器 ===== */
.avatar-pick-row{display:flex;gap:16px;flex-wrap:wrap;margin-top:6px;}
.avatar-pick{
  cursor:pointer;border:2.5px solid var(--line);border-radius:50%;
  width:84px;height:84px;overflow:hidden;padding:0;background:var(--surface);
  transition:border-color .15s, box-shadow .15s, transform .12s ease;
}
.avatar-pick:hover{transform:translateY(-2px);box-shadow:var(--card-shadow-lift);}
.avatar-pick img{width:100%;height:100%;object-fit:cover;display:block;}
.avatar-pick.selected{border-color:var(--primary);box-shadow:0 0 0 3px rgba(66,133,244,.25);}
.avatar-pick-label{text-align:center;font-size:13px;color:var(--ink-soft);margin-top:5px;}
.profile-preview{
  width:96px;height:96px;border-radius:50%;overflow:hidden;flex:none;
  background:var(--surface);border:3px solid var(--card-border);
}
.profile-preview img{width:100%;height:100%;object-fit:cover;}
/* 等級唯讀卡 */
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;}
.stat-box{background:var(--surface);border-radius:16px;padding:16px 18px;}
.stat-box .stat-num{font-size:26px;font-weight:700;background:var(--aurora-wide);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;}
.stat-box .stat-label{font-size:13px;color:var(--ink-soft);margin-top:2px;}

@media (max-width:640px){
  #app{padding:16px 12px 70px;}
  .app-header{gap:12px;padding:14px 16px;}
  .header-actions{margin-left:0;width:100%;justify-content:flex-end;}
  .exam-timer{font-size:17px;padding:8px 16px;top:10px;right:10px;}
  .notif-panel{width:min(320px,86vw);}
  .score-big{font-size:42px;}
  .tabs{width:100%;}
  .mode-grid{grid-template-columns:1fr;}
}

/* ============================================================
   設計系統 v2：新增共用元件（Playful yet Professional）
   ============================================================ */

/* ---- 膠囊（連續達標 / 星星） ---- */
.capsule{
  display:inline-flex;align-items:center;gap:5px;
  padding:5px 12px;border-radius:999px;font-size:13px;font-weight:900;
  white-space:nowrap;
}
.capsule-streak{background:var(--gold-soft);color:#8A5A00;box-shadow:0 0 0 3px rgba(255,184,0,.16);}
.capsule-stars{background:var(--brand-soft);color:var(--brand);}

/* ---- 標籤 ---- */
.tag{display:inline-block;font-size:11.5px;font-weight:800;padding:3px 9px;border-radius:8px;white-space:nowrap;}
.tag-brand{background:var(--brand-soft);color:var(--brand);}
.tag-gold{background:var(--gold-soft);color:#8A5A00;}
.tag-mint{background:var(--mint-soft);color:var(--mint-dark);}
.tag-coral{background:var(--coral-soft);color:var(--coral-dark);}
.tag-slate{background:var(--slate-150);color:var(--ink-soft);}
.chip-grade{background:var(--brand-soft);color:var(--brand);font-size:12px;font-weight:800;padding:4px 10px;border-radius:8px;white-space:nowrap;}

/* ---- 分段進度條 ---- */
.seg-bar{display:flex;gap:4px;flex:1;}
.seg-bar > i{flex:1;height:11px;border-radius:999px;background:var(--line);overflow:hidden;position:relative;}
.seg-bar > i > b{position:absolute;inset:0;width:0;background:var(--mint);border-radius:999px;transition:width .45s cubic-bezier(.2,.8,.2,1);}
.seg-bar > i.done > b{width:100%;}
.seg-bar > i.cur > b{width:55%;}

/* ---- 選項卡（答題）---- */
.choice{
  display:flex;align-items:center;gap:12px;width:100%;text-align:left;
  background:#fff;border:2px solid var(--line);border-radius:var(--card-radius);
  padding:14px 16px;font-family:inherit;font-size:16px;font-weight:800;color:var(--ink);
  box-shadow:0 3px 0 0 var(--line);cursor:pointer;
  transition:border-color .12s,background .12s,transform .06s,box-shadow .06s;
}
.choice:active{transform:translateY(3px);box-shadow:0 0 0 0 var(--line);}
.choice .key{
  width:32px;height:32px;border-radius:8px;flex:none;display:grid;place-items:center;
  background:var(--surface);border:1.5px solid var(--line);font-size:14px;font-weight:900;color:var(--ink-soft);
}
.choice:hover{border-color:#93B4FF;background:#F7FAFF;}
.choice.sel{border-color:var(--brand);background:rgba(42,92,232,.05);}
.choice.sel .key{background:var(--brand);border-color:var(--brand);color:#fff;}
.choice.correct{border-color:var(--mint);background:var(--mint-soft);}
.choice.correct .key{background:var(--mint);border-color:var(--mint);color:#fff;}
.choice.wrong{border-color:var(--coral);background:var(--coral-soft);}
.choice.wrong .key{background:var(--coral);border-color:var(--coral);color:#fff;}

/* ---- 底部回饋托盤 ---- */
.tray{
  position:fixed;left:0;right:0;bottom:0;z-index:210;
  transform:translateY(115%);transition:transform .3s cubic-bezier(.2,.9,.25,1);
  border-top:1.5px solid transparent;
}
.tray.show{transform:translateY(0);}
.tray-good{background:var(--mint-soft);border-top-color:#A7E8CE;}
.tray-bad{background:var(--coral-soft);border-top-color:#FBB6C3;}
.tray-in{max-width:760px;margin:0 auto;padding:16px 20px;display:flex;align-items:center;gap:14px;flex-wrap:wrap;}
.tray-icon{width:44px;height:44px;border-radius:50%;display:grid;place-items:center;flex:none;color:#fff;font-size:22px;font-weight:900;}
.tray-good .tray-icon{background:var(--mint);box-shadow:0 4px 0 0 var(--mint-dark);}
.tray-bad .tray-icon{background:var(--coral);box-shadow:0 4px 0 0 var(--coral-dark);}
.tray-txt{flex:1;min-width:180px;}
.tray-title{font-size:17px;font-weight:900;}
.tray-good .tray-title{color:#0B7A57;}
.tray-bad .tray-title{color:#B42340;}
.tray-why{font-size:14px;font-weight:700;color:var(--ink-soft);margin-top:3px;line-height:1.55;}

/* ---- 學習路徑（課題節點清單） ---- */
.path-group-title{font-size:13px;font-weight:800;color:var(--ink-soft);letter-spacing:.4px;margin:18px 0 6px;}
.path{display:flex;flex-direction:column;}
.path-row{display:flex;align-items:center;gap:14px;padding:12px 2px;border-bottom:1px solid var(--line);}
.path-row:last-child{border-bottom:none;}
.path-node{
  width:50px;height:50px;border-radius:50%;display:grid;place-items:center;flex:none;position:relative;
  font-size:20px;font-weight:900;color:#fff;
}
.path-node.done{background:var(--mint);box-shadow:0 3px 0 0 var(--mint-dark),0 0 0 4px var(--mint-soft);}
.path-node.active{
  width:56px;height:56px;background:var(--brand);
  box-shadow:0 4px 0 0 var(--brand-dark),0 8px 16px rgba(42,92,232,.26),0 0 0 5px var(--brand-soft);
  animation:pathFloat 2.4s ease-in-out infinite;
}
@keyframes pathFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
.path-node.idle{background:#fff;border:2px dashed var(--line);color:var(--muted);}
.path-info{flex:1;min-width:0;}
.path-name{font-size:15px;font-weight:800;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.tip-start{
  position:absolute;top:-38px;left:50%;transform:translateX(-50%);
  background:var(--brand);color:#fff;font-size:12px;font-weight:900;letter-spacing:.6px;
  padding:5px 12px;border-radius:8px;white-space:nowrap;box-shadow:0 6px 14px rgba(42,92,232,.3);
}
.tip-start::after{
  content:'';position:absolute;bottom:-4px;left:50%;transform:translateX(-50%) rotate(45deg);
  width:9px;height:9px;background:var(--brand);border-radius:2px;
}

/* ============================================================
   導覽：頂部 tab bar（app.js renderNav 產生；每個尺寸都一樣）
   ============================================================ */
#app-nav{
  position:fixed;top:0;left:0;right:0;z-index:60;
  display:flex;align-items:center;gap:4px;overflow-x:auto;scrollbar-width:none;
  padding:8px max(12px, calc((100vw - 900px) / 2));
  background:rgba(255,255,255,.94);backdrop-filter:blur(12px);
  border-bottom:1px solid var(--line);
}
#app-nav::-webkit-scrollbar{display:none;}
#app-nav .nav-item{
  display:inline-flex;align-items:center;gap:6px;flex:none;
  padding:7px 13px;border-radius:999px;font-family:inherit;font-size:13.5px;font-weight:800;
  color:var(--ink-soft);text-decoration:none;background:none;border:none;cursor:pointer;
  transition:background .15s,color .15s;white-space:nowrap;
}
#app-nav .nav-item svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;}
#app-nav .nav-item.active{background:var(--brand-soft);color:var(--brand);}
#app-nav .nav-item:hover{background:var(--surface);text-decoration:none;}
body.has-nav #app{padding-top:72px;}

/* Owner 控制台：所有 button 都有立體下壓效果（配合 owner_home.js 嘅 inline 3D 陰影） */
body.page-owner button{transition:transform .06s ease,box-shadow .06s ease,background .15s ease;}
body.page-owner button:not(:disabled):active{transform:translateY(3px);box-shadow:none;}

/* Owner 控制台：大題卡片。明細留喺分頁，呢度只負責一眼睇完。 */
.own-dash{display:flex;flex-direction:column;gap:14px;}
.own-top{display:flex;justify-content:space-between;align-items:flex-end;gap:12px;flex-wrap:wrap;}
.own-top h2{margin:0;font-size:26px;letter-spacing:-.3px;}
.own-top p{margin:4px 0 0;color:var(--ink-soft);font-size:14px;font-weight:700;}
.own-kpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;}
.own-kpi{
  background:#fff;border:1px solid var(--line);border-radius:16px;padding:16px 16px 14px;
  box-shadow:var(--card-shadow);min-width:0;
}
.own-kpi span{display:block;font-size:13px;color:var(--ink-soft);font-weight:800;}
.own-kpi b{display:block;margin-top:6px;font-size:34px;line-height:1;font-variant-numeric:tabular-nums;letter-spacing:-.8px;}
.own-kpi em{display:block;margin-top:8px;font-style:normal;font-size:12.5px;color:#64748B;font-weight:700;}
.own-kpi.alert{border-color:#FECACA;background:#FFF7F7;}
.own-kpi.alert b{color:var(--coral-dark);}
.own-grid{display:grid;grid-template-columns:1.35fr .9fr;gap:14px;align-items:start;}
.own-card{
  background:#fff;border:1px solid var(--line);border-radius:16px;padding:16px 18px 18px;
  box-shadow:var(--card-shadow);
}
.own-card h3{margin:0;font-size:16px;}
.own-card .own-sub{margin:4px 0 12px;color:var(--ink-soft);font-size:13px;font-weight:700;}
.own-card-h{display:flex;justify-content:space-between;align-items:flex-start;gap:8px;}
.own-matrix{display:grid;grid-template-columns:46px repeat(4,minmax(0,1fr));gap:6px;align-items:stretch;}
.own-mx-h,.own-mx-g{font-size:12px;font-weight:800;color:#64748B;display:flex;align-items:center;justify-content:center;}
.own-cell{
  border:1px solid var(--line);border-radius:10px;min-height:42px;padding:6px 4px;cursor:pointer;
  font-family:inherit;font-weight:800;font-size:13px;background:var(--surface);color:#94A3B8;
}
.own-cell.usable{background:var(--mint-soft);color:var(--mint-dark);border-color:#B7E7D4;}
.own-cell.shelf{background:var(--gold-soft);color:#8A5A00;border-color:#F3E0A8;}
.own-cell.on{outline:2px solid var(--brand);outline-offset:1px;}
.own-legend{display:flex;gap:12px;flex-wrap:wrap;margin-top:10px;font-size:12px;color:#64748B;font-weight:800;}
.own-legend i{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:4px;vertical-align:-1px;}
.own-todo{display:flex;flex-direction:column;gap:8px;}
.own-todo button{
  text-align:left;font-family:inherit;font-weight:800;font-size:14px;cursor:pointer;
  border-radius:12px;padding:10px 12px;border:1px solid var(--line);background:#fff;color:var(--ink);
}
.own-todo button.warn{background:var(--coral-soft);border-color:#FECACA;color:var(--coral-dark);}
.own-todo button.gold{background:var(--gold-soft);border-color:#F3E0A8;color:#8A5A00;}
.own-roles{display:flex;flex-wrap:wrap;gap:8px;}
.own-role{background:var(--surface);border-radius:999px;padding:6px 12px;font-size:13px;font-weight:800;}
.own-filters{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin:0 0 12px;}
.own-filters button.on{background:var(--brand);color:#fff;border-color:var(--brand);}
.own-pager{display:flex;align-items:center;justify-content:flex-end;gap:8px;margin-top:12px;font-size:13px;font-weight:800;color:#64748B;}
.own-banner{border-radius:12px;padding:10px 14px;font-size:14px;font-weight:800;margin-bottom:12px;}
.own-banner.bad{background:#FFF1F3;border:1px solid #FBB6C3;color:var(--coral-dark);}
.own-banner.ok{background:var(--mint-soft);border:1px solid #B7E7D4;color:var(--mint-dark);}
@media (max-width:980px){
  .own-kpis{grid-template-columns:1fr 1fr;}
  .own-grid{grid-template-columns:1fr;}
  .own-kpi b{font-size:28px;}
}

/* ============================================================
   比例收細（v2.1）：整體 UI 縮細一級，內容置中
   ============================================================ */
body{font-size:15px;}
#app{max-width:900px;padding:18px 16px 80px;}
body.has-nav #app{padding-top:70px;}
h1{font-size:22px;} h2{font-size:18px;} h3{font-size:16px;}
.card{padding:18px;margin-bottom:14px;}
.btn{padding:10px 20px;font-size:14.5px;}
.btn-lg{padding:12px 24px;font-size:16px;}
.btn-sm{padding:7px 13px;font-size:13px;}
.choice{padding:11px 14px;font-size:15px;border-radius:14px;}
.choice .key{width:28px;height:28px;font-size:13px;}
.path-node{width:42px;height:42px;font-size:17px;}
.path-node.active{width:48px;height:48px;}
.path-row{padding:10px 2px;gap:12px;}
.path-name{font-size:14.5px;}
.field{margin-bottom:14px;}
.input,.field input[type=text],.field input[type=password],.field input[type=number],.field select,.field textarea{
  padding:10px 13px;font-size:15px;border-radius:12px;
}
.tabs{padding:4px;margin-bottom:16px;}
.tab{padding:7px 16px;font-size:14.5px;}
.tabs-sub .tab{font-size:13.5px;padding:5px 13px;}
.question{padding:16px;margin-bottom:12px;}
.q-prompt{font-size:15.5px;}
.q-opt{padding:10px 14px;font-size:15px;border-radius:14px;margin-bottom:7px;}
.exam-timer{font-size:17px;padding:8px 16px;}
.score-big{font-size:44px;}
.subject-grid{gap:12px;}
.subject-card{padding:18px 14px;border-radius:16px;}
.subject-card .sub-icon{font-size:26px;}
.subject-card .sub-name{font-size:16px;}
.mode-grid{gap:10px;}
.mode-card{padding:14px 16px;border-radius:16px;}
.mode-name{font-size:15px;}
.mode-desc{font-size:12.5px;}
.count-btn{font-size:15px;padding:8px 18px;}
.grade-btn{font-size:15px;padding:9px 0;}
.app-header{padding:14px 18px;gap:14px;margin-bottom:16px;border-radius:16px;}
.header-avatar{width:52px;height:52px;}
.header-name{font-size:18px;}
.loading-card{padding:26px 34px;min-width:240px;border-radius:22px;}
.loading-timer{font-size:24px;}
.loading-title{font-size:15.5px;}
.banner,.banner-warn{padding:11px 15px;border-radius:14px;font-size:13.5px;}
.list-row{padding:11px 4px;gap:12px;}
.tag{font-size:11px;padding:2px 8px;}

/* ===== v2.2 修訂 ===== */
/* 載入遮罩：秒數細啲 */
.loading-timer{font-size:19px;font-weight:800;margin:6px 0 2px;}
.loading-title{font-size:15px;}

/* 頂部 tab bar：似 Chrome tab，色彩鮮明、置中 */
#app-nav{justify-content:center;gap:8px;padding:10px max(12px,calc((100vw - 900px)/2)) 0;align-items:flex-end;}
#app-nav .nav-item{
  border-radius:12px 12px 0 0;padding:9px 18px;font-size:13.5px;
  border:1.5px solid transparent;border-bottom:none;
}
#app-nav .nav-item:nth-child(3n+1){background:var(--brand-soft);color:var(--brand);border-color:#D8E3FB;}
#app-nav .nav-item:nth-child(3n+2){background:var(--mint-soft);color:var(--mint-dark);border-color:#B6E7D2;}
#app-nav .nav-item:nth-child(3n+3){background:var(--gold-soft);color:#8A5A00;border-color:#F5DCA6;}
#app-nav .nav-item.active:nth-child(3n+1){background:var(--brand);color:#fff;border-color:var(--brand);}
#app-nav .nav-item.active:nth-child(3n+2){background:var(--mint);color:#fff;border-color:var(--mint);}
#app-nav .nav-item.active:nth-child(3n+3){background:var(--gold);color:#4A2E00;border-color:var(--gold);}
#app-nav .nav-item:hover{filter:brightness(.97);text-decoration:none;}

/* 作答進度：freeze 喺頂 */
.exam-progress{position:sticky;top:64px;z-index:30;}

/* 頭像大啲 */
.profile-preview{width:124px;height:124px;}
.avatar-pick{width:96px;height:96px;}

/* 科目／年級選擇：卡片式，eye catching */
.pick-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px;}
.pick-card{
  font-family:inherit;cursor:pointer;text-align:left;color:var(--ink);
  border:2px solid var(--line);background:#fff;border-radius:16px;
  padding:14px 16px;box-shadow:0 3px 0 0 var(--line);
  transition:transform .06s,box-shadow .06s,border-color .15s,background .15s;
}
.pick-card:active{transform:translateY(3px);box-shadow:0 0 0 0 var(--line);}
.pick-card .pc-icon{font-size:24px;line-height:1;}
.pick-card .pc-name{font-size:16px;font-weight:900;margin-top:6px;}
.pick-card .pc-sub{font-size:12px;color:var(--ink-soft);margin-top:2px;}
.pick-card:hover{border-color:#93B4FF;}
.pick-card.on{border-color:var(--brand);background:var(--brand-soft);box-shadow:0 3px 0 0 var(--brand);}
.pick-card.on .pc-name{color:var(--brand);}
.grade-grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(74px,1fr));gap:8px;}
.grade-pill{
  font-family:inherit;cursor:pointer;font-size:15px;font-weight:900;color:var(--ink);
  border:2px solid var(--line);background:#fff;border-radius:14px;padding:12px 0;
  box-shadow:0 3px 0 0 var(--line);transition:transform .06s,box-shadow .06s;
}
.grade-pill:active{transform:translateY(3px);box-shadow:0 0 0 0 var(--line);}
.grade-pill.on{background:var(--brand);border-color:var(--brand);color:#fff;box-shadow:0 3px 0 0 var(--brand-dark);}

/* AI 生成嘅 SVG 通常只有 viewBox，會撐滿卡片；限制闊度免得過大 */
.q-svg svg{max-width:440px;width:100%;height:auto;}

/* ===== 登入頁 v2.2 ===== */
/* (1) 主 tab（個人用戶／機構用戶／家長）同機構子 tab：整組 pill 置中。
       pill 收窄到內容闊度再 auto margin 居中；窄螢幕自動用盡可用闊度。 */
.auth-wrap .tabs{
  display:flex;width:fit-content;max-width:100%;
  margin-left:auto;margin-right:auto;justify-content:center;
}

/* (2) 背景裝飾：柔和漸變光暈 + 幼細圓點矩陣。
       純 CSS、零額外 DOM、唔用外部圖片；z-index:-1 + pointer-events:none
       → 畫喺所有內容下面，永遠唔會擋住輸入框／按鈕。
       .owner-entry（系統管理員入口）係登入頁獨有元素 → body:has() 令註冊頁保持乾淨。 */
body:has(.owner-entry) .auth-wrap::before,
body:has(.owner-entry) .auth-wrap::after{
  content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
}
/* 光暈：brand 藍（左上）・mint（右上）・gold（右下）・periwinkle（左下） */
body:has(.owner-entry) .auth-wrap::before{
  background:
    radial-gradient(46vmax 34vmax at 4% -4%, rgba(42,92,232,.22) 0%, rgba(42,92,232,.08) 44%, rgba(42,92,232,0) 72%),
    radial-gradient(40vmax 32vmax at 100% 10%, rgba(16,185,129,.20) 0%, rgba(16,185,129,.07) 44%, rgba(16,185,129,0) 72%),
    radial-gradient(44vmax 34vmax at 84% 104%, rgba(255,184,0,.22) 0%, rgba(255,184,0,.08) 44%, rgba(255,184,0,0) 72%),
    radial-gradient(38vmax 30vmax at 6% 96%, rgba(109,140,240,.18) 0%, rgba(109,140,240,.06) 44%, rgba(109,140,240,0) 72%);
  animation:authGlowDrift 26s ease-in-out infinite alternate;
}
/* 圓點紋理：中央（表單卡所在）用 mask 淡走，卡面同文字保持乾淨 */
body:has(.owner-entry) .auth-wrap::after{
  background-image:
    radial-gradient(circle, rgba(42,92,232,.34) 1.4px, rgba(42,92,232,0) 1.5px),
    radial-gradient(circle, rgba(16,185,129,.34) 1.4px, rgba(16,185,129,0) 1.5px);
  background-size:34px 34px, 34px 34px;
  background-position:0 0, 17px 17px;
  opacity:.5;
  -webkit-mask-image:radial-gradient(72% 66% at 50% 44%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 42%, rgba(0,0,0,.85) 100%);
  mask-image:radial-gradient(72% 66% at 50% 44%, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 42%, rgba(0,0,0,.85) 100%);
}
/* 極輕微嘅呼吸／飄移，令背景唔死板（純 transform，唔觸發 layout） */
@keyframes authGlowDrift{
  from{transform:translate3d(0,0,0) scale(1);}
  to{transform:translate3d(0,-1.4%,0) scale(1.03);}
}
@media (prefers-reduced-motion:reduce){
  body:has(.owner-entry) .auth-wrap::before{animation:none;}
}
/* 窄螢幕：光暈改成更貼邊、圓點收細，唔好同表單爭注意力 */
@media (max-width:640px){
  body:has(.owner-entry) .auth-wrap::before{
    background:
      radial-gradient(80vmax 48vmax at -12% -8%, rgba(42,92,232,.18) 0%, rgba(42,92,232,0) 70%),
      radial-gradient(72vmax 46vmax at 112% 14%, rgba(16,185,129,.16) 0%, rgba(16,185,129,0) 70%),
      radial-gradient(76vmax 48vmax at 88% 110%, rgba(255,184,0,.18) 0%, rgba(255,184,0,0) 70%);
  }
  body:has(.owner-entry) .auth-wrap::after{
    opacity:.38;background-size:28px 28px, 28px 28px;background-position:0 0, 14px 14px;
  }
}

/* ============================================================
   隨機背景相（bg1–bg3，每 session 一張；app.js pickBackground 設定）
   重點：CSS cover 自動裁切（唔會變形）+ 模糊 + 半透明遮罩保持可讀
   ============================================================ */
body.has-bg::before{
  content:'';position:fixed;inset:-28px;z-index:-2;
  background-image:var(--bg-img);
  background-size:cover;         /* 自動裁切填滿，唔會拉伸變形 */
  background-position:center;
  background-repeat:no-repeat;
  /* 模糊：只睇到大概構圖；輕微放大避免模糊邊緣露白 */
  filter:blur(10px) saturate(1.06) brightness(1.03);
  transform:scale(1.06);
}
body.has-bg::after{
  content:'';position:fixed;inset:0;z-index:-1;
  /* 冷白遮罩：壓低背景對比，令卡片同文字清楚易讀 */
  background:rgba(248,250,252,.62);
}
/* 窄螢幕（風景相裁切較多）：再降低背景存在感，確保細字清晰 */
@media (max-width:640px){
  body.has-bg::before{filter:blur(12px) saturate(1.04) brightness(1.04);}
  body.has-bg::after{background:rgba(248,250,252,.70);}
}

/* ============================================================
   窄螢幕頂部導覽（max-width:600px）
   起因：360px 闊嘅手機（家長 4 個 tab）tab 會爆，要橫捲先睇得晒。
   只喺呢個 media query 入面覆寫，上面 #app-nav 原有 rule 一律不動。
   箭嘴：由置中改靠左、間距同 padding 收窄、字同 icon 縮一級。
   實測闊度（家長 4 tab：主頁／指派／我的檔案／登出）：
     68 + 68 + 93 + 68 + gap 4×3 + nav padding 12×2 ≈ 333px < 360px
   → 唔使橫捲、唔會切字。高度亦由約 53px 降到約 49px（只會變矮）。
   ============================================================ */
@media (max-width:600px){
  #app-nav{justify-content:flex-start;gap:4px;}
  #app-nav .nav-item{padding:8px 11px;font-size:12.5px;}
  #app-nav .nav-item svg{width:15px;height:15px;}
}
/* 再窄（≤340px，例如 iPhone SE 一代）：導覽再收一級，
   否則 4 個 tab（主頁／指派／我的檔案／登出）仍然會差少少爆出（實測 320px 時 341px）。 */
@media (max-width:340px){
  #app-nav{gap:2px;}
  #app-nav .nav-item{padding:7px 8px;font-size:12px;}
  #app-nav .nav-item svg{width:14px;height:14px;}
}

/* ============================================================
   作答頁分頁器（quick 分批出題）
   每頁 5 題，「上一頁／下一頁」；背景仲出緊題嗰陣，
   喺「下一頁」原位顯示「出緊題…」加三點動畫（重用 .loading-spin 嘅 bouncing dots）。
   ============================================================ */
.exam-pager{display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap;margin:6px 0 14px;}
.exam-pager-info{font-size:13px;font-weight:800;color:#64748B;font-variant-numeric:tabular-nums;}
.exam-busy{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:800;color:var(--primary);}
.exam-busy .loading-spin{margin:0;gap:5px;}
.exam-busy .loading-spin span{width:8px;height:8px;animation-duration:.9s;}

/* ============================================================
   家長學習報告（parent_report.js，route #/parent/report）
   折線圖係自己手畫嘅 inline SVG（固定 viewBox 300×120）：
   CSS width:100% + max-width 令佢自適應卡片闊度又唔會拉到變形；
   線／點／參考線嘅顏色全部用 design tokens。
   ============================================================ */
.rp-chart{display:block;width:100%;max-width:420px;height:auto;margin:8px 0 0;}
.rp-chart .grid{stroke:var(--line);stroke-width:1;stroke-dasharray:4 4;}
.rp-chart .avg{stroke:var(--mint);stroke-width:1.4;stroke-dasharray:6 4;}
.rp-chart .line{fill:none;stroke:var(--brand);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;}
.rp-chart .dot{fill:#fff;stroke:var(--brand);stroke-width:2.2;}
.rp-chart .axis{fill:var(--ink-soft);font-size:9.5px;font-weight:800;}

/* 答對率長條（純 div + width%，唔用圖表庫） */
.rp-bar{height:12px;border-radius:999px;background:var(--surface);overflow:hidden;}
.rp-bar > i{display:block;height:100%;border-radius:999px;}
.rp-fill-coral{background:var(--coral);}
.rp-fill-gold{background:var(--gold);}
.rp-fill-mint{background:var(--mint);}

/* 成績下跌用嘅膠囊（`.capsule` 本身冇紅色款） */
.capsule-coral{background:var(--coral-soft);color:var(--coral-dark);box-shadow:0 0 0 3px rgba(244,63,94,.14);}

/* 窄螢幕：圖表食盡闊度，「返主頁」掣獨佔一行 */
@media (max-width:600px){
  .rp-chart{max-width:none;}
  .rp-back{width:100%;}
}

/* ============================================================
   Owner 控制台（owner_home.js）四項改動：全部只 append，上面任何 rule 一律唔動。
   ① 總覽「用戶」卡：近 7 日「有登入」（usage.seen7）同「有交卷」（usage.actors7）並排，
      兩個數分開顯示，唔會當成同一件事。
   ② 參考試卷庫每一行：「更多」選單（常設只留改分類／手動分類），展開只影響自己嗰行。
   ③ 戶口管理：「顯示管理員同停用」開關（同現有角色篩選掣一齊排、一齊用）。
   ============================================================ */
.own-seen{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:8px;
  background:var(--surface);border:1px solid var(--line);border-radius:12px;
  padding:10px 12px;margin:2px 0 12px;
}
.own-seen .own-seen-h{font-size:13px;font-weight:800;color:var(--ink-soft);}
.own-seen b{font-size:15px;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums;}
.own-seen i{font-style:normal;font-weight:800;color:#CBD5E1;}
.own-seen em{flex:1 1 100%;font-style:normal;font-size:12.5px;font-weight:700;color:#64748B;}

/* 「更多」選單：td 係 white-space:nowrap，呢度要還原 normal + 換行，
   否則窄螢幕會撐闊表格（橫向 scroll 由原本嘅表格容器負責，唔會影響成頁）。 */
.own-rowmenu{display:none;white-space:normal;margin-top:8px;padding:8px;gap:6px;border:1px dashed var(--line);border-radius:12px;background:var(--surface);}
.own-rowmenu.open{display:flex;flex-wrap:wrap;}
.own-rowmenu > button{flex:0 1 auto;min-width:0;}

/* 「顯示管理員同停用」：未開用虛線邊，同其他角色篩選掣一眼分得開 */
.own-filters .own-toggle{border-style:dashed;}
.own-filters .own-toggle.on{border-style:solid;}

@media (max-width:600px){
  .own-seen b{font-size:14px;}
  .own-rowmenu > button{flex:1 1 auto;}
}

/* ============================================================
   家長頁 v4.11：截止時間快捷 pill 嘅「自訂日期」細字 link
   （唔搶眼嘅細字掣；只係一個獨立 class，上面任何 rule 都冇改）
   ============================================================ */
.due-link{
  font-family:inherit;font-size:13px;font-weight:800;color:var(--brand);
  background:none;border:none;padding:0;cursor:pointer;text-decoration:underline;
}
.due-link:hover{color:var(--brand-dark);}

/* ============================================================
   Owner 用量分析（public/js/pages/owner_analytics.js，owner 控制台其中一個分頁）
   全部係新 class，上面任何 rule 一律冇改。
   ============================================================ */
.an-card{padding:16px 18px 18px;margin-bottom:14px;}            /* 同總覽 .own-card 一樣緊密 */
.an-kpis{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:10px;}
.an-kpis .own-kpi{padding:13px 14px 12px;}
.an-kpis .own-kpi b{font-size:26px;letter-spacing:-.5px;}       /* 細過總覽嘅 34px，唔搶眼 */
.an-rates{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:12px;}
.an-apicalls{font-size:12.5px;font-weight:700;color:#64748B;font-variant-numeric:tabular-nums;}
.an-range{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
.an-pills{display:flex;gap:6px;flex-wrap:wrap;}
.an-pills .grade-pill{padding:8px 16px;font-size:13.5px;}
.an-datelabel{display:flex;align-items:center;gap:6px;flex-wrap:wrap;font-size:13.5px;font-weight:800;color:var(--ink-soft);}
.an-date{font-family:inherit;font-size:13.5px;font-weight:700;color:var(--ink);background:#fff;
  border:1px solid var(--line);border-radius:10px;padding:7px 10px;}
.an-subh{font-size:14px;font-weight:800;color:var(--ink);margin:2px 0 8px;}
.an-errface{font-size:34px;line-height:1;}
.an-errmsg{font-size:16px;font-weight:800;margin-top:6px;}
.an-bigcost{font-size:30px;font-weight:900;line-height:1.1;font-variant-numeric:tabular-nums;letter-spacing:-.6px;}
.an-costmeta{margin-top:6px;font-size:13px;font-weight:700;color:var(--ink-soft);font-variant-numeric:tabular-nums;}

/* 折線圖（自己手畫 inline SVG）：食盡卡面闊度、保持比例，唔會拉變形 */
.an-chart{display:block;width:100%;max-width:760px;height:auto;margin:6px 0 0;}
.an-chart .grid{stroke:var(--line);stroke-width:1;stroke-dasharray:4 4;}
.an-chart .base{stroke:#CBD5E1;stroke-width:1.4;}
.an-chart .exams{fill:none;stroke:var(--brand);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;}
.an-chart .tokens{fill:none;stroke:var(--mint);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;}
.an-chart .dot-exams{fill:#fff;stroke:var(--brand);stroke-width:2;}
.an-chart .dot-tokens{fill:#fff;stroke:var(--mint);stroke-width:2;}
.an-chart .axis{fill:var(--ink-soft);font-size:10px;font-weight:800;}
.an-chart .axis-left{fill:var(--brand);}
.an-chart .axis-right{fill:var(--mint-dark);}
.an-legend{display:flex;gap:14px;flex-wrap:wrap;align-items:center;font-size:12.5px;color:var(--ink-soft);font-weight:800;margin-top:8px;}
.an-legend i{display:inline-block;width:16px;height:3px;border-radius:2px;margin-right:6px;vertical-align:3px;}

/* 窄螢幕：大數由 5 格 → 3 格 → 2 格；日期輸入改為一行一個，避免撐爆 */
@media (max-width:1180px){.an-kpis{grid-template-columns:repeat(3,minmax(0,1fr));}}
@media (max-width:760px){
  .an-kpis{grid-template-columns:1fr 1fr;}
  .an-kpis .own-kpi b{font-size:22px;}
  .an-chart{max-width:none;}
}
@media (max-width:480px){
  .an-kpis .own-kpi{padding:11px 12px 10px;}
  .an-pills .grade-pill{padding:7px 12px;font-size:13px;}
  .an-datelabel{display:grid;grid-template-columns:auto;gap:4px;width:100%;}
  .an-date{width:100%;max-width:220px;}
  .an-bigcost{font-size:26px;}
}

/* 折線圖軸標籤：SVG 用固定 viewBox，字級會跟容器闊度縮放 →
   窄螢幕（容器只有 240–300px）要放大 viewBox 內嘅字級，落到手機先睇得清。
   1280px 桌面維持 10px（實際 render ≈ 12px，同卡面細字一致）。 */
@media (max-width:760px){
  .an-chart .axis{font-size:15px;}
  .an-chart .exams,.an-chart .tokens{stroke-width:2.6;}
}

/* ============================================================
   R4／R5 全域調整（2026-09-30）
   ⚠️ 全部係檔尾 append，上面任何 rule 一律冇改；唯一例外係
   `.card{margin-bottom:var(--gap)}`（明確批准嘅覆寫；值同現行有效值一樣）。
   ============================================================ */

/* ---------- R5-1 間距 token（:root 追加；現有變數一個都冇改） ---------- */
:root{
  --gap:14px;      /* 卡／區塊之間嘅標準間距（= 原本 .card 嘅有效值 14px） */
  --gap-sm:10px;   /* 同一組元素之間嘅細間距（清單列、通知面板） */
}

/* ---------- R5-1 全站卡間距統一（唯一批准嘅覆寫） ----------
   原本 `.card{margin-bottom:14px}`（上面「比例收細」段）→ var(--gap) = 14px，
   數值一樣，所以視覺上唔應該有變（實測兩張相鄰卡 gap 仍然一樣）。 */
.card{margin-bottom:var(--gap);}

/* ============================================================
   R4 背景相（body.has-bg）
   原本：桌面 blur(10px)／窄螢幕 blur(12px) —— 模糊得太緊要，睇唔出係相。
   現在：桌面 blur(4px)／窄螢幕 blur(3px)，保留柔化但構圖同明暗層次睇得到。
   遮罩（::after）**完全冇改**（桌面 .62、窄螢幕 .70）→ 白卡上面嘅深色字
   對比照舊；--bg-img 來源、background-size:cover、background-position:center
   一律冇動 → 相唔會變形。
   ============================================================ */
body.has-bg::before{filter:blur(4px) saturate(1.06) brightness(1.03);}
/* 窄螢幕：螢幕細、相裁切多，同一 px 數嘅模糊相對上更明顯 → 再細一級 */
@media (max-width:640px){
  body.has-bg::before{filter:blur(3px) saturate(1.04) brightness(1.04);}
  /* 窄螢幕遮罩跟桌面一致（.70 → .62）：原本 .70 + 直向裁切令相幾乎睇唔到 */
  body.has-bg::after{background:rgba(248,250,252,.62);}
}

/* ============================================================
   R5-2／R5-5 通知掣同清單群組
   ① `.btn-sm` 觸控目標 ≥40px（原本實測高 34px，細過手指目標）。
   ② 清單列組內間距、通知面板內距改用 --gap-sm。
   ⚠️ 通知面板嗰兩粒掣（前往／標記已讀）之間嘅水平距離係
      components.js 用 inline `gap:12px` 做嘅（inline 優先），所以
      呢度刻意**唔加** margin-left —— 加咗會疊加成 22px，撐走原本設計。
   ============================================================ */
.btn-sm{min-height:40px;}
.list-row{gap:var(--gap-sm);}
.notif-panel{padding:var(--gap-sm);}

/* ============================================================
   R5-3 作答頁
   ① 作答頁係「專心模式」，冇 #app-nav。原本 sticky top:64px 係預留畀
      頂部 tab bar 嘅，冇 nav 就會吊住一片空白 → 收窄到 12px。
      有 nav 嘅頁面完全不受影響（selector 限死 body:not(.has-nav)）。
   ② 30 題卷嘅分段進度：375px 實測每格只有 6.6px 闊（壓扁到睇唔到）。
      加 min-width:8px 令格仔有下限，容器同時可以橫捲（唔會撐闊版面）。
      捲軸收埋：.seg-bar 只有 11px 高，出捲軸會頂高成張進度卡。
   ============================================================ */
body:not(.has-nav) .exam-progress{top:12px;}
.seg-bar{overflow-x:auto;scrollbar-width:none;}
.seg-bar::-webkit-scrollbar{display:none;}
.seg-bar > i{min-width:8px;}

/* ============================================================
   R5-4 Header 手機收緊（≤600px）
   隱藏「最新通知」標籤同未讀預覽文字（得返個鈴），桌面保留預覽。
   selector 由 components.js 攞：`.header-notif-tag`（tag tag-slate）、
   `.header-notif-preview`。桌面預覽 180px + ellipsis 本身係
   components.js 嘅 inline style，呢度用 CSS 固化多一次（inline 冇咗都唔會走樣）。
   ============================================================ */
.header-notif-preview{max-width:180px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
@media (max-width:600px){
  .header-notif-tag{display:none;}
  .header-notif-preview{display:none;}
}

/* ============================================================
   家長頁 v4.14（多子女 chips + 三分頁大粒化 + 寬螢幕橫放 + 統一 dropdown）
   ⚠️ 全部係新 class（`.m-*` 前綴），上面任何 rule 一律冇改、一個字都冇郁。
   ============================================================ */

/* ---------- 仔女 chips（多過一個仔女先出；排喺 header 之下、三分頁之上） ---------- */
.m-childbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:12px;}
.m-childbar-label{font-size:13px;font-weight:800;color:var(--ink-soft);}
.m-childrow{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0;}
.m-child{
  font-family:inherit;cursor:pointer;display:inline-flex;align-items:center;gap:8px;
  background:#fff;border:2px solid var(--line);border-radius:999px;padding:8px 16px;
  box-shadow:0 3px 0 0 var(--line);color:var(--ink);
  transition:transform .06s,box-shadow .06s,background .15s,border-color .15s;
}
.m-child:active{transform:translateY(3px);box-shadow:0 0 0 0 var(--line);}
.m-child-name{font-size:15px;font-weight:900;}
.m-child-grade{font-size:12px;font-weight:800;color:var(--ink-soft);}
.m-child.on{background:var(--brand);border-color:var(--brand);color:#fff;box-shadow:0 3px 0 0 var(--brand-dark);}
.m-child.on .m-child-grade{color:rgba(255,255,255,.9);}

/* ---------- 三分頁（大粒、明顯；active = 實色底 + 白字） ---------- */
.m-seg{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-bottom:16px;}
.m-seg-btn{
  font-family:inherit;cursor:pointer;text-align:center;color:var(--ink);
  background:#fff;border:2px solid var(--line);border-radius:16px;padding:13px 10px 12px;
  box-shadow:0 3px 0 0 var(--line);
  transition:transform .06s,box-shadow .06s,background .15s,border-color .15s;
}
.m-seg-btn:active{transform:translateY(3px);box-shadow:0 0 0 0 var(--line);}
.m-seg-btn .m-seg-ico{display:block;font-size:21px;line-height:1;}
.m-seg-btn .m-seg-name{display:block;font-size:17px;font-weight:900;margin-top:7px;}
.m-seg-btn .m-seg-sub{display:block;font-size:12px;font-weight:700;color:var(--ink-soft);margin-top:3px;line-height:1.35;}
.m-seg-btn.active,
.m-seg-btn.active:hover{background:var(--brand);border-color:var(--brand);color:#fff;box-shadow:0 3px 0 0 var(--brand-dark);}
.m-seg-btn.active .m-seg-sub{color:rgba(255,255,255,.92);}

/* ---------- 統一 dropdown（唔用瀏覽器預設樣；跟 .input／.grade-pill 一致） ---------- */
.m-select{
  font-family:inherit;font-size:14.5px;font-weight:800;color:var(--ink);
  width:100%;max-width:100%;background-color:#fff;
  border:2px solid var(--line);border-radius:14px;padding:11px 38px 11px 14px;
  box-shadow:0 3px 0 0 var(--line);
  -webkit-appearance:none;appearance:none;cursor:pointer;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23475569' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 12px center;background-size:16px 16px;
  transition:border-color .15s,box-shadow .06s;
}
.m-select:focus{outline:none;border-color:var(--brand);}
.m-select:disabled{background-color:var(--slate-150);color:#94A3B8;cursor:not-allowed;}
.m-select option{font-weight:700;color:var(--ink);}

/* ---------- 寬螢幕橫放（≥900px 自動多欄；窄螢幕自動變一欄） ----------
   用 auto-fit：空嘅格會收埋，剩返嘅格平均分滿一行（3–4 個 field 就一行放晒）。 */
.m-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:14px;}
.m-grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px;}

/* ---------- 主要掣置中（.btn-block 100% + max-width → flex 居中） ---------- */
.m-center{display:flex;justify-content:center;margin-top:14px;}
.m-center > .btn{width:100%;}

/* ---------- 年級鎖：靜態 chip（唔可以揀） ---------- */
.m-graderow{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:16px;}
.m-gradechip{font-size:13.5px;padding:6px 14px;}

/* ---------- 範圍：課題多選 pill ---------- */
.m-topicbox{
  border:1.5px dashed var(--line);border-radius:14px;background:var(--surface);
  padding:10px;max-height:230px;overflow-y:auto;
}
.m-topicgrid{display:flex;flex-wrap:wrap;gap:8px;}
.m-topicpill{padding:8px 14px;font-size:13.5px;font-weight:800;border-radius:12px;}
.m-advlink{
  font-family:inherit;font-size:13px;font-weight:800;color:var(--brand);
  background:none;border:none;padding:0;cursor:pointer;text-decoration:underline;display:block;
}
.m-advlink:hover{color:var(--brand-dark);}

/* ---------- 通知設定：兩個提醒（各自 toggle ＋ 時間 dropdown） ---------- */
.m-notifcell{border:1.5px solid var(--line);border-radius:14px;background:var(--surface);padding:12px 14px;}
.m-notiftitle{font-size:15px;font-weight:900;margin-bottom:4px;}
.m-notifctl{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:12px;}
.m-notifctl .grade-pill{flex:none;min-width:104px;padding:9px 14px;font-size:13.5px;}
.m-notifctl .m-select{flex:1 1 150px;width:auto;min-width:0;}

/* ---------- 窄螢幕（≤600px）：三分頁照樣三格但收細，唔會橫向溢出 ---------- */
@media (max-width:600px){
  .m-seg{gap:8px;}
  .m-seg-btn{padding:11px 6px 10px;border-radius:14px;}
  .m-seg-btn .m-seg-ico{font-size:19px;}
  .m-seg-btn .m-seg-name{font-size:15.5px;}
  .m-seg-btn .m-seg-sub{font-size:11px;}
  .m-child{padding:7px 13px;}
  .m-grid,.m-grid2{gap:12px;}
  .m-center{margin-top:12px;}
}
@media (max-width:380px){
  .m-seg{gap:6px;}
  .m-seg-btn{padding:10px 4px;}
  .m-seg-btn .m-seg-name{font-size:14.5px;}
  .m-seg-btn .m-seg-sub{font-size:10.5px;}
}

/* ============================================================
   家長頁 v4.15（兩分頁 + 選擇範圍 pop-up + 逐個鐘／逐日時間 + 等寬掣列）
   ⚠️ 全部係新 class（`.m-*` 前綴），上面任何 rule 一律冇改、一個字都冇郁。
   ============================================================ */

/* ---------- 兩分頁（派卷／設定）：.m-seg 本身寫死 3 欄，用 modifier 收做 2 欄 ---------- */
.m-seg.m-seg-2{grid-template-columns:repeat(2,minmax(0,1fr));}

/* ---------- 等寬掣列（10／20／30 題：同一行、等寬、撐滿卡片闊度） ---------- */
.m-btnrow{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-top:10px;}
.m-btnrow > .count-btn{width:100%;min-width:0;min-height:44px;padding:10px 4px;margin:0;}

/* ---------- 選擇範圍（主頁嗰粒掣 ＋ 已揀課題 chips） ---------- */
.m-rangechips{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:10px;}
.m-rangechip{
  display:inline-flex;align-items:center;gap:8px;max-width:100%;
  background:var(--brand-soft);border:1.5px solid var(--brand);border-radius:999px;
  padding:6px 8px 6px 14px;color:var(--brand-dark);font-size:13.5px;font-weight:800;
}
.m-rangechip-x{
  font-family:inherit;cursor:pointer;flex:none;width:22px;height:22px;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:12px;font-weight:900;line-height:1;color:var(--brand-dark);
  background:#fff;border:1.5px solid var(--brand);border-radius:999px;
}
.m-rangechip-x:hover{background:var(--brand);color:#fff;}

/* ---------- 選擇範圍 pop-up（modal 內容） ---------- */
.m-randrow{margin-bottom:12px;}
.m-randpill{width:100%;padding:12px 14px;}
.m-rangepills{
  display:flex;flex-wrap:wrap;gap:8px;align-items:flex-start;
  max-height:46vh;overflow-y:auto;padding:2px;
}

/* ---------- 窄螢幕（≤600px／≤380px）：等寬掣列照樣三格，收細字同 padding ---------- */
@media (max-width:600px){
  .m-btnrow{gap:8px;}
  .m-btnrow > .count-btn{font-size:15px;padding:10px 2px;}
  .m-rangepills{max-height:40vh;}
}
@media (max-width:380px){
  .m-btnrow > .count-btn{font-size:14px;}
  .m-btnrow > .count-btn .count-time{font-size:11px;}
}

/* ============================================================================
   v4.17 R8：Header 頭像尺寸（原本喺 components.js 用 inline 92px 覆寫，改成 CSS 控制）
   注意：style.css:736 嗰條 .header-avatar{52px} 係「比例收細」全域 block（唔係 media query），
   所以呢兩條要一齊 append：desktop 條後出贏 :736，mobile 條排最後 → 兩邊都啱。
   ============================================================================ */
.header-avatar{width:92px;height:92px;}
@media (max-width:600px){.header-avatar{width:52px;height:52px;}}

/* ============================================================================
   v4.17 R11：填充／短答／長答輸入控件（基礎樣式喺 components.js 用 inline 寫死，
   呢度只補 placeholder／hover／focus／disabled 同格位間距；!important 係故意——
   基礎 border 係 inline style，一定要 !important 先蓋得過。
   次序：hover 喺前、focus 喺後（同時 hover+focus 時品牌色勝）。
   ============================================================================ */
.blank-slot{display:inline-block;vertical-align:middle;margin:0 3px;}
.question input[type=text].q-text:hover,
.question textarea.q-textarea:hover,
.question select.q-select.blank-input:hover{border-color:#93B4FF !important;}
.question input[type=text].q-text:focus,
.question textarea.q-textarea:focus,
.question select.q-select.blank-input:focus{border-color:var(--brand) !important;}
.question input::placeholder,
.question textarea::placeholder{color:#94A3B8;font-weight:500;}
.question input[type=text].q-text:disabled,
.question textarea.q-textarea:disabled,
.question select.q-select.blank-input:disabled{background:var(--surface);opacity:1;color:var(--ink-soft);}

/* ============================================================================
   v5.1 Wave 2：社交系統 —— 手機版導覽收成 icon-only
   nav 由 3 項（主頁／我的檔案／登出）加到 5 項（＋朋友／團隊），≤600px 會逼爆，
   所以收埋文字（label 喺 <span> 內），只留 icon；label 保留喺 title attribute（app.js 設定）。
   ============================================================================ */
@media (max-width:600px){
  #app-nav{gap:4px;}
  #app-nav .nav-item{padding:9px 12px;min-height:44px;}
  #app-nav .nav-item > span{display:none;}
  #app-nav .nav-item svg{width:20px;height:20px;}
}

/* ============================================================================
   v5.4 F8：市場推廣首頁 landing（全部 .landing-* 新 class；上面任何 rule 冇改）
   DOM：.landing-page = [.landing-sales][.landing-login]
   桌機 ≥1024px 兩欄：左銷售區（約 55–60%）／右 400px 登入卡（重用 login.js 表單）
   <1024px 反轉：登入卡最上 →「了解學庫 ↓」→ 銷售區在後
   #app 平常上限 900px（style.css:700），兩欄唔夠闊 → 只有 landing 在時放寬
   （:has 同登入頁光暈同一套寫法；唔支援 :has 時退回 900px，一樣唔會橫滾）。
   var() 一律寫 fallback，因為 design tokens 可能未定義 --fs-*。
   ============================================================================ */
body:has(.landing-page) #app{max-width:1080px;}

.landing-page{display:flex;align-items:flex-start;gap:34px;}
.landing-sales{flex:1 1 auto;min-width:0;}
.landing-login{flex:0 0 400px;width:400px;max-width:100%;min-width:0;}

/* 嵌入嘅登入卡：跟全站白卡，唔用登入頁嘅置中留白（只 scope 喺 .landing-login 內） */
.landing-login .auth-wrap{max-width:100%;margin:0;}
.landing-login .auth-logo{margin-bottom:18px;}
.landing-login .auth-logo h1{font-size:24px;}
.landing-login .owner-entry{margin-top:20px;}

/* ---------- 左：銷售區 ---------- */
.landing-h1{
  font-size:var(--fs-3xl,40px);line-height:1.28;letter-spacing:-.4px;
  margin:6px 0 14px;font-weight:900;
}
.landing-lead{
  font-size:var(--fs-lg,17px);line-height:1.7;color:var(--ink-soft);
  margin:0 0 22px;font-weight:800;overflow-wrap:break-word;
}
.landing-points{list-style:none;margin:0 0 26px;padding:0;display:flex;flex-direction:column;gap:14px;}
.landing-point{display:flex;align-items:flex-start;gap:12px;line-height:1.6;}
.landing-ico{font-size:22px;line-height:1.35;flex:none;}
.landing-ptext{font-size:var(--fs-md,16px);min-width:0;overflow-wrap:anywhere;}
.landing-cta{display:flex;flex-direction:column;align-items:flex-start;gap:10px;}
.landing-go{text-decoration:none;}
.landing-note{margin:0;font-size:13.5px;color:var(--ink-soft);font-weight:700;}
.landing-foot{
  margin-top:30px;padding-top:16px;border-top:1px solid var(--line);
  font-size:12.5px;color:var(--ink-soft);font-weight:700;
}
.landing-foot a{margin-left:4px;}

/* ---------- <1024px：反轉（登入卡最上、「了解學庫 ↓」、銷售區在後） ---------- */
.landing-jump{display:none;}
@media (max-width:1023px){
  .landing-page{flex-direction:column;gap:20px;}
  .landing-login{order:1;flex:none;width:100%;max-width:460px;margin:0 auto;padding-top:4px;}
  .landing-sales{order:2;width:100%;}
  .landing-h1{font-size:var(--fs-3xl,32px);}
  .landing-jump{
    display:block;margin:16px auto 0;padding:10px 20px;
    font-family:inherit;font-size:14.5px;font-weight:800;color:var(--brand);
    background:var(--brand-soft);border:1.5px solid var(--brand);border-radius:999px;cursor:pointer;
  }
  .landing-jump:active{transform:translateY(1px);}
}
@media (max-width:380px){
  .landing-h1{font-size:var(--fs-3xl,28px);}
}

/* ============================================================================
   v5.4 F3＋F4（設計代幣、共用元件樣式）
   ⚠️ 本段全部追加於檔案末端，上面所有既有 rule 一個字都沒有改動。
   內容：① 字級代幣 scale
        ② 本次批准的覆寫（h2 頁標題統一 18px、.pill／.tag-subject／.chip-grade
           統一成 .tag 的外觀、.btn-sm 最低高度 40px）
        ③ 共用元件樣式（人物列 .person-row-*、未讀紅點 .unread-badge、
           十檔稱號色階 .lv-tier-1…10 與 .badge-lv-1…10）
   ============================================================================ */

/* ---------- ① 字級 scale ----------
   新寫的程式碼一律使用 var(--fs-*)（例如 font-size:var(--fs-lg)），
   不得再直接寫死像素值（例如 font-size:18px）；
   既有寫死的數值先不動，日後改版才逐處換成代幣。 */
:root{
  --fs-2xs:10.5px;
  --fs-xs:12px;
  --fs-sm:13.5px;
  --fs-base:15px;
  --fs-md:16.5px;
  --fs-lg:18px;
  --fs-xl:22px;
  --fs-2xl:28px;
  --fs-3xl:38px;

  /* 十檔稱號色階：第 1 檔最淺的灰綠 → 第 10 檔紫金。
     同一組色值同時供等級標籤（.lv-tier-*）與頂部等級徽章（.badge-lv-*）使用，
     保證兩邊永遠同色。 */
  --lv-1:#7D9084;
  --lv-2:#4B966C;
  --lv-3:#19978A;
  --lv-4:#6F9A2A;
  --lv-5:#A89320;
  --lv-6:#D2761F;
  --lv-7:#C9503F;
  --lv-8:#B8407C;
  --lv-9:#A855F7;
  --lv-10:#6D28D9;

  /* 原本 --diamond 是主色藍 #2A5CE8，跟品牌色完全同色；
     改成紫金，同時避開 #2A5CE8（RGB 距離 86、色相相差 39 度）。 */
  --diamond:#6D28D9;
}

/* ---------- ② 本次批准的覆寫 ---------- */

/* 頁標題統一 18px。friends.js（inline 26px）與 chat.js 的頁首 h2 都在
   #app > .card > div 之下；challenge.js 題目卡的 h2 直接在 #app > .card 之下。
   兩處都是 inline font-size，inline 優先度高於任何選擇器，所以要用 !important
   才蓋得過（不改動 pages/*.js 的唯一做法）。選擇器已收窄到這三頁的實際位置。 */
#app > .card > div > h2,
#app > .card > h2{font-size:var(--fs-lg) !important;}

/* .pill／.tag-subject／.chip-grade 統一成 .tag 的外觀（保留 class 名，向後兼容）：
   尺寸完全跟 .tag 的最終值相同（font-size 11px／padding 2px 8px／radius 8px／
   font-weight 800／nowrap），底色與文字色取 .tag-slate 的中性配色。 */
.pill,
.tag-subject,
.chip-grade{
  display:inline-block;
  font-size:11px;
  font-weight:800;
  padding:2px 8px;
  border-radius:8px;
  white-space:nowrap;
  background:var(--slate-150);
  color:var(--ink-soft);
  border:none;
}
/* 語意色要放在統一樣式之後才不會被蓋掉（底色仍保留原本語意） */
.pill-pending{background:#FEF7E0;color:#B26A00;}
.pill-done{background:#E6F4EA;color:#1E8E3E;}
.pill-info{background:#E8F0FE;color:#3367D6;}

/* .btn-sm 最低高度 40px：正式規範。
   原本 R5-2 已經有同一條（style.css 前半段），這裡再寫一次作為規範確認，
   內容完全相同，不會造成任何視覺改動。 */
.btn-sm{min-height:40px;}

/* ---------- ③ F4 共用元件樣式 ---------- */

/* 人物列（UI.personRow）：頭像 40px 圓 → 姓名＋等級標籤 → 一句細字 → 右側節點 */
.person-row{display:flex;align-items:center;gap:12px;padding:10px 2px;min-width:0;}
.person-row-avatar{
  width:40px;height:40px;border-radius:50%;overflow:hidden;flex:none;
  background:var(--surface);display:flex;align-items:center;justify-content:center;
}
.person-row-avatar img,
.person-row-avatar svg{width:100%;height:100%;object-fit:cover;display:block;}
.person-row-main{flex:1 1 auto;min-width:0;}
.person-row-top{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.person-row-name{font-size:var(--fs-base);font-weight:900;line-height:1.35;}
.person-row-sub{
  font-size:var(--fs-sm);color:var(--ink-soft);margin-top:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.person-row-right{flex:none;margin-left:auto;display:flex;align-items:center;gap:8px;}
.person-row-tap{cursor:pointer;}

/* 未讀紅點（UI.unreadBadge）：導覽列、對話清單、朋友清單共用同一種外觀 */
.unread-badge{
  display:inline-block;min-width:20px;box-sizing:border-box;padding:1px 6px;
  border-radius:var(--radius-pill);background:var(--coral);color:#fff;
  font-size:var(--fs-2xs);font-weight:900;line-height:16px;text-align:center;
  white-space:nowrap;flex:none;vertical-align:middle;
}

/* 十檔稱號色階（標籤）：實色底＋白字，跟 .badge-lv-* 用同一組色值 */
.lv-tier-1{background:var(--lv-1);color:#fff;}
.lv-tier-2{background:var(--lv-2);color:#fff;}
.lv-tier-3{background:var(--lv-3);color:#fff;}
.lv-tier-4{background:var(--lv-4);color:#fff;}
.lv-tier-5{background:var(--lv-5);color:#fff;}
.lv-tier-6{background:var(--lv-6);color:#fff;}
.lv-tier-7{background:var(--lv-7);color:#fff;}
.lv-tier-8{background:var(--lv-8);color:#fff;}
.lv-tier-9{background:var(--lv-9);color:#fff;}
.lv-tier-10{background:var(--lv-10);color:#fff;}

/* 十檔稱號色階（頂部等級徽章 .badge 的配色；.badge 本身的尺寸不變） */
.badge-lv-1{background:var(--lv-1);}
.badge-lv-2{background:var(--lv-2);}
.badge-lv-3{background:var(--lv-3);}
.badge-lv-4{background:var(--lv-4);}
.badge-lv-5{background:var(--lv-5);}
.badge-lv-6{background:var(--lv-6);}
.badge-lv-7{background:var(--lv-7);}
.badge-lv-8{background:var(--lv-8);}
.badge-lv-9{background:var(--lv-9);}
.badge-lv-10{background:var(--lv-10);}

/* ============================================================================
   v5.4 F8-b：首頁宣傳圖輪播（Hero Carousel）
   ⚠️ 本段全部追加於檔案末端，上面所有既有 rule 一個字都沒有改動。
   DOM：.landing-hero（position:relative、tabindex="0"）
          > .landing-track > .landing-slide ×5（第 5 格是首張的複製格，用於無縫循環）
          ＋ button.landing-arrow-prev／.landing-arrow-next
          ＋ .landing-dots > .landing-dot > i
   圖片內的標語已經印在圖上，前端不得在圖上另加任何文字。
   var() 一律寫 fallback（design tokens 可能未定義）。
   ============================================================================ */

.landing-hero{
  position:relative;
  width:100%;
  margin:0 0 26px;
  border-radius:16px;
  overflow:hidden;                          /* 圓角需要剪裁輪播內容 */
  background:var(--slate-150,#EEF1F6);      /* 圖片未載入前的底色 */
  outline:none;                             /* 改用下面的 :focus-visible 款式 */
}
.landing-hero:focus-visible{outline:3px solid var(--brand,#2A5CE8);outline-offset:3px;}

.landing-track{
  display:flex;
  width:100%;
  transition:transform .6s ease;            /* 向左滾一張的動畫 */
  will-change:transform;
}
.landing-slide{flex:0 0 100%;min-width:100%;}
.landing-slide img{
  display:block;
  width:100%;
  height:auto;
  aspect-ratio:4/3;                         /* 一律 4:3 */
  object-fit:cover;                         /* 裁切填滿，不變形 */
}

/* ---------- 容器底部置中的指示點 ---------- */
.landing-dots{
  position:absolute;
  left:0;right:0;bottom:10px;
  z-index:2;
  display:flex;align-items:center;justify-content:center;gap:6px;
}
.landing-dot{
  display:flex;align-items:center;justify-content:center;
  width:24px;height:28px;padding:0;margin:0;
  background:none;border:none;cursor:pointer;
}
.landing-dot i{
  display:block;width:8px;height:8px;border-radius:999px;
  background:#fff;
  border:1px solid rgba(0,0,0,.18);
  box-shadow:0 1px 2px rgba(0,0,0,.16);
  transition:width .3s ease,background .3s ease;
}
.landing-dot.is-active i{
  width:16px;                               /* 選中：品牌藍 16px 膠囊 */
  background:var(--brand,#2A5CE8);
  border-color:transparent;
}
.landing-dot:focus-visible{outline:2px solid var(--brand,#2A5CE8);outline-offset:1px;border-radius:6px;}

/* ---------- 左右箭咀：只在支援 hover 的裝置出現（觸控裝置完全不顯示） ---------- */
.landing-arrow{display:none;}
@media (hover:hover){
  .landing-arrow{
    position:absolute;top:50%;transform:translateY(-50%);z-index:3;
    display:flex;align-items:center;justify-content:center;
    width:44px;height:44px;min-width:44px;min-height:44px;padding:0 0 3px;
    border:none;border-radius:50%;cursor:pointer;
    background:rgba(0,0,0,.32);color:#fff;
    font-family:inherit;font-size:26px;line-height:1;
    opacity:0;                              /* 平常隱藏，hover 時淡出顯示 */
    transition:opacity .3s ease;
  }
  .landing-hero:hover .landing-arrow,
  .landing-hero:focus-within .landing-arrow{opacity:.85;}
  .landing-arrow:hover{opacity:1;}
  .landing-arrow-prev{left:10px;}
  .landing-arrow-next{right:10px;}
}

/* ---------- 減少動態效果：不做滑動動畫（自動播放由 JS 依同一個 media query 關閉） ---------- */
@media (prefers-reduced-motion: reduce){
  .landing-track{transition:none;}
  .landing-dot i{transition:none;}
}

/* ============================================================================
   v5.4c：Landing 改版（純白底、一屏不捲動、左圖右登入卡、圖上不加文字）
   ⚠️ 本段全部追加於檔案末端。上面 v5.4／v5.4b 的 .landing-* 舊規則仍在，
      這裡用同一批選擇器覆寫（同特異度、後寫者生效），上面段落一個字都沒有改動。
   白底與鎖捲動只在「畫面上有 .landing-page」時生效（body:has），
   登入後其他頁面的隨機背景相（body.has-bg）完全不受影響。
   ============================================================================ */

/* ---------- 只在 landing：白底、隱藏背景相、鎖死捲動、#app 滿版 ---------- */
body:has(.landing-page){background:#fff;overflow:hidden;}
body:has(.landing-page).has-bg::before,
body:has(.landing-page).has-bg::after{display:none;content:none;}
body:has(.landing-page) #app{max-width:none;margin:0;padding:0;}

/* ---------- 一屏兩欄：左圖（彈性）＋ 右登入卡（固定 460px） ---------- */
.landing-page{
  position:fixed;inset:0;z-index:1;
  display:flex;align-items:stretch;gap:0;
  background:#fff;
}
.landing-sales{
  position:relative;flex:1 1 auto;min-width:0;
  overflow:hidden;background:#fff;
}
.landing-login{
  flex:0 0 400px;width:400px;max-width:100%;
  display:flex;align-items:flex-start;justify-content:center;
  padding:28px 28px;
  background:#fff;
  border-left:1px solid var(--line,#E4E9F0);
  overflow-y:auto;
}
/* 卡片垂直置中（margin auto 在溢出時會自動收成 0，捲動起點仍然看得到卡頂） */
.landing-login .auth-wrap{max-width:100%;width:100%;margin:auto 0;}

/* ---------- 左欄輪播：撐滿整個左欄，圖片 cover 填滿（不變形） ---------- */
.landing-sales .landing-hero{
  position:absolute;inset:0;
  width:100%;height:100%;
  margin:0;border-radius:0;background:#fff;
}
.landing-track{height:100%;}
.landing-slide{height:100%;}
.landing-slide img{
  width:100%;height:100%;
  aspect-ratio:auto;                 /* 改由容器決定框位 */
  object-fit:contain;                /* 整張宣傳圖完整顯示、不裁切也不變形 */
}
/* 底部指示點：白底上改用深灰圓點，選中為品牌藍 */
.landing-dots{bottom:14px;}
.landing-dot i{
  background:rgba(15,23,42,.22);border-color:transparent;box-shadow:none;
}
.landing-dot.is-active i{background:var(--brand,#2A5CE8);}

/* ---------- <1024px：上下排列（圖在上、登入卡在下），合共一個視窗高度 ---------- */
@media (max-width:1023px){
  .landing-page{flex-direction:column;gap:0;}
  .landing-sales{
    order:1;flex:0 0 auto;
    height:34vh;height:34dvh;min-height:150px;
  }
  .landing-login{
    order:2;flex:1 1 auto;width:100%;max-width:none;
    align-items:flex-start;
    padding:18px 18px 24px;
    border-left:none;border-top:1px solid var(--line,#E4E9F0);
  }
  .landing-login .auth-wrap{max-width:420px;margin:0 auto;padding-top:2px;}
  .landing-login .auth-logo{margin-bottom:10px;}
  .landing-login .owner-entry{margin-top:14px;}
}
@media (max-width:380px){
  .landing-sales{height:28vh;height:28dvh;min-height:120px;}
}

/* ============================================================================
   v5.4d：Landing 微調（用戶 2026-10 review）
   ① 左右箭咀低調啲（由黑色實心圓 → 白色半透明細圓＋淡邊）
   ② 圖 ＋ 登入卡做「一組」整體置中：整組最大闊度＝圖高 × 圖比例 ＋ 400px，
      兩者痴埋一齊，剩餘白位平均分去左右兩邊（唔會出現圖同卡之間嘅空洞）
   ③ 滑鼠移到圖上唔再暫停自動播放（由 landing.js 移除 hover 暫停）
   ⚠️ 全部追加於檔尾，上面段落一個字都沒有改動。
   ============================================================================ */

/* ② 整組置中 */
.landing-page{
  justify-content:center;
  max-width:calc(100vh * 1.3389 + 400px);    /* 1600 ÷ 1195 = 1.3389（宣傳圖比例） */
  max-width:calc(100dvh * 1.3389 + 400px);
  margin:0 auto;                             /* position:fixed + inset:0 → 左右平均留白 */
}

/* ① 箭咀：細啲、白底半透明、淡邊，唔再搶眼 */
.landing-arrow{
  width:38px;height:38px;min-width:38px;min-height:38px;
  padding:0 0 2px;
  background:rgba(255,255,255,.86);
  color:#475569;
  border:1px solid rgba(15,23,42,.08);
  box-shadow:0 1px 6px rgba(15,23,42,.14);
  font-size:19px;
}
.landing-hero:hover .landing-arrow,
.landing-hero:focus-within .landing-arrow{opacity:.6;}
.landing-arrow:hover{opacity:1;background:#fff;}
.landing-arrow-prev{left:14px;}
.landing-arrow-next{right:14px;}

/* 手機／平板：維持上下排列，取消整組置中嘅 max-width */
@media (max-width:1023px){
  .landing-page{justify-content:flex-start;max-width:none;margin:0;}
}

/* ============================================================================
   v5.4f：宣傳圖輪播微調（用戶 2026-10 review）
   ① 自動播放改為 3 秒（landing.js 的 AUTOPLAY_MS），次序每次載入都撈亂
   ② 用戶明確要求「要打橫碌走」→ 連「減少動態效果」之下嘅 transition:none 都要覆蓋返，
      令滑動動畫一定睇得到（後寫者生效：呢條喺上面那個 @media 之後，所以贏）。
   ============================================================================ */
.landing-track{transition:transform .6s ease;}

/* ============================================================================
   v5.4h：滑動動畫由 .6s 放慢 50% → .9s（用戶：3 秒一張太快、滑動令人頭暈）
   自動播放間隔改回 5 秒（landing.js 的 AUTOPLAY_MS，唔關 CSS 事）。
   後寫者生效：呢條喺上面兩條 .landing-track transition 之後，所以一定贏。
   ⚠️ landing.js 的 SETTLE_MS 一定要大過呢個秒數（現為 960ms），
      否則無縫循環會喺動畫未完就跳位。
   ============================================================================ */
.landing-track{transition:transform .9s ease;}

/* ============================================================================
   v5.4j：品牌標記改用新 logo 圖（public/assets/logo-128.png，由 logo/ 彩色版縮出）
   ⚠️ 全部追加於檔尾，上面 `.brand-mark-lg` 原有 rule 一字未改，只係後寫者覆蓋。
   - 舊設計：藍色立體方塊（background:var(--brand) ＋ 陰影）＋ 白色書本 SVG。
   - 新設計：直接顯示 logo 圖（圖本身已經有白底同構圖），所以取消藍底同陰影，
     尺寸由 58px 加大到 64px，令圖入面嘅標記睇得清楚少少。
   ============================================================================ */
.brand-mark-lg{
  background:none;
  box-shadow:none;
  width:64px;
  height:64px;
  border-radius:0;
  overflow:visible;
}
.brand-mark-lg img{width:100%;height:100%;display:block;object-fit:contain;}

/* ============================================================================
   v5.8（2026-10-03）：導覽 icon 更清楚 ＋ 登出永遠靠最右（手機都寫明「登出」）
   ① 朋友＝對話氣泡（msg）、團隊＝幾個人（team）、我的檔案維持單人（user）
      —— 圖示本體在 app.js 的 NAV_ICONS。
      icon 由 17px → 18px、stroke-width 2.4 → 2.6；手機 20px → 22px（線寬 2.7）。
      只改大小同線寬；顏色、active 底色、nth-child 彩色配色一律保留。
   ② 登出掣（.nav-item-logout）用 margin-left:auto 永遠靠最右。
      ≤600px 其他項照舊 icon-only（上面 `#app-nav .nav-item > span{display:none}` 不變），
      只有登出用更精準的 selector 還原文字；朋友未讀紅點係 <b data-nav-unread>（唔係 span），
      故此不受影響。
   全部係檔尾 append，上面既有 rule 一律冇改。
   ============================================================================ */
#app-nav .nav-item svg{width:18px;height:18px;stroke-width:2.6;}
#app-nav .nav-item-logout{margin-left:auto;}
@media (max-width:600px){
  #app-nav .nav-item svg{width:22px;height:22px;stroke-width:2.7;}
  /* 手機版唯一例外：登出保留「登出」兩個字（橫向夠位，文字＋icon 並排） */
  #app-nav .nav-item-logout > span{display:inline;}
}
@media (max-width:360px){
  /* 最窄（320px 一類，5 個項目）：icon 收一級、左右 padding 各收 2px，
     確保連「登出」文字都放得落而且不用橫捲（實測 320px 時總闊約 280px < 305px）。 */
  #app-nav .nav-item svg{width:20px;height:20px;}
  #app-nav .nav-item{padding:9px 10px;}
}

/* ============================================================================
   v5.8（2026-10-03）：Owner 控制台左側選單改成「可收埋抽屜」
   舊：188px 選單卡一直貼在左邊（position:sticky），桌機同手機都佔位、遮住內容。
   新：平時完全唔佔位（position:fixed ＋ 預設 translateX(-102%)），撳左上角「☰ 選單」才由左邊
       滑出（transform .2s ＋ 半透明遮罩）；撳遮罩／撳 ✕／按 Esc／揀了分頁之後自動收埋。
       抽屜係 fixed，打開時唔會推動主內容，亦唔會令頁面橫向滾動；桌機同手機行為一樣。
   相關 DOM 由 owner_home.js 產生（.own-menu-btn／.own-scrim／.own-drawer／.own-drawer-nav）。
   全部係新 class ＋ 檔尾 append，上面既有 rule 一律冇改。
   ============================================================================ */
.own-layout{
  max-width:1640px;margin:0 auto;padding:16px 22px 60px;
  font-family:'Noto Sans TC',sans-serif;color:#1F1F1F;
}
.own-content{min-width:0;max-width:100%;}
.own-menu-btn{
  display:inline-flex;align-items:center;gap:8px;margin:0 0 14px;
  font-family:inherit;font-size:14.5px;font-weight:800;color:#2B2F38;
  background:#fff;border:1px solid var(--line);border-radius:12px;
  padding:9px 16px;cursor:pointer;box-shadow:var(--card-shadow);
}
.own-menu-btn:hover{background:var(--surface);}
.own-scrim{
  position:fixed;inset:0;z-index:64;background:rgba(15,23,42,.42);
  opacity:0;visibility:hidden;transition:opacity .2s ease,visibility .2s;
}
.own-scrim.open{opacity:1;visibility:visible;}
.own-drawer{
  position:fixed;top:0;bottom:0;left:0;z-index:65;
  width:272px;max-width:86vw;overflow-y:auto;
  background:#fff;border-right:1px solid var(--line);
  box-shadow:0 14px 44px rgba(15,23,42,.2);
  transform:translateX(-102%);visibility:hidden;
  transition:transform .2s ease,visibility .2s;
}
.own-drawer.open{transform:translateX(0);visibility:visible;}
.own-drawer-h{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:14px 12px 10px;border-bottom:1px solid var(--line);
}
.own-drawer-h b{font-size:15px;font-weight:900;}
.own-drawer-x{
  font-family:inherit;font-size:17px;line-height:1;font-weight:900;color:#64748B;
  background:none;border:none;border-radius:10px;padding:7px 11px;cursor:pointer;
}
.own-drawer-x:hover{background:var(--surface);color:var(--ink);}
.own-drawer-nav{padding:12px;}

/* ----------------------------------------------------------------------------
   Owner 手機版（≤700px）：只在新 media query 入面覆寫，上面既有 rule 一律唔動。
   ① 收窄 #app 同 .own-layout 的左右 padding（原本 22px ＋ 22px，384px 螢幕只剩約 296px 可用）；
   ② KPI 明確 2 欄、大數 34px → 26px；③ 總覽 .own-grid 兩欄變一欄；
   ④ 題庫矩陣／卡片收窄；⑤ 卡片加 min-width:0，令表格的 overflow-x:auto 容器真正只在卡內橫捲。
   ---------------------------------------------------------------------------- */
@media (max-width:700px){
  body.page-owner #app{padding:70px 10px 40px;}
  .own-layout{padding:0 0 40px;}
  .own-kpis{grid-template-columns:1fr 1fr;gap:10px;}
  .own-kpi{padding:12px 12px 11px;}
  .own-kpi b{font-size:26px;}
  .own-grid{grid-template-columns:1fr;}
  .own-card{padding:14px 14px 16px;min-width:0;}
  .own-top h2{font-size:22px;}
  .own-matrix{grid-template-columns:34px repeat(4,minmax(0,1fr));gap:4px;}
  .own-cell{min-height:38px;font-size:12.5px;padding:5px 2px;}
  .own-mx-h,.own-mx-g{font-size:11px;}
  .own-pager{margin-top:10px;}
  .own-drawer{width:260px;}
}

/* ============================================================================
   v5.9（2026-10-03）：Desktop / Tablet / Mobile 三尺寸專業排版修正
   依據 UI_REVIEW_MOBILE_2026-10-03.md 逐項落實（P0-1 字重／P0-2 overflow 保險／
   P0-3 safe-area／P1-2 底部緩衝同層級／P2-1 touch target／P2-2 nav／P2-3 m-seg／
   P2-4 標題孤行／P2-6 landing／P3 美學收尾）。
   ⚠️ 全部追加於檔尾；上面既有 rule 一個字都冇改，一律靠「後寫者生效」覆寫。
   ⚠️ 相關 JS（exam.js／components.js／chat.js／landing.js）由其他 agent 負責，
      呢一段只提供 CSS class 契約，唔郁任何 .js。
   ============================================================================ */

/* ---------------------------------------------------------------------------
   T1（P0-1）全域字重 700 → 500、行高 1.65 → 1.58
   中文 700 比 500 闊好多，一句行到尾剩兩三粒字就會被逼落下一行（尾字孤行）。
   index.html 只載 Noto Sans TC 400／500／700，所以用 500（用 550 會被瀏覽器
   snap 去最近字重，冇意思）。
   500 唔會令品牌「變瘦冇力」：所有控件、標題、標籤本身都有自己嘅 700–900
   （.btn 800／.choice 800／.tag 800／.pill 800／#app-nav .nav-item 800／
   .m-seg-btn .m-seg-name 900／h1–h4 700／.q-no 900／.section-title 900…
   全部原封不動）。
   --------------------------------------------------------------------------- */
body{font-weight:500;line-height:1.58;}

/* 承 T1：以下幾類原本**冇自己 font-weight**、靠 body 700 撐住，父層降到 500
   之後會明顯變虛（或者連 bolder 一齊跌一級），所以喺呢度補回權重。 */
.q-opt{font-weight:700;}            /* 選項列：同 .choice(800) 睇齊，答案唔應該輕飄飄 */
.chip{font-weight:700;}             /* 排句題字詞磚：可撳嘅控件 */
table.fee th{font-weight:700;}      /* 收費表標題格（table.fee td 保持 500，讀數據更清） */
.own-kpi b{font-weight:900;}        /* owner KPI 大數字：本來靠 bolder 由 700 升 900，
                                       父層變 500 就會跌到 700，一定要寫死 */
.toast{font-weight:600;}            /* 深色底提示：500 喺深底上會覺得虛 */
.avatar-pick-label{font-weight:600;}/* 頭像選項標籤（label 類） */

/* 長文閱讀區（文章、解析）CJK 行高畀返 1.7：body 1.58 係為咗介面文字收緊，
   連續段落收得太緊會反而難讀。 */
.q-passage,.explain-box{line-height:1.72;}
/* 細字：13px 用 1.58 只有 20.5px，略緊；1.62 令兩行細字唔會黐埋。 */
.small{line-height:1.62;}

/* ---------------------------------------------------------------------------
   T2（P0-2）全頁 overflow 保險
   任何一個超闊元素（AI 出嘅長 URL、內嵌 table、nowrap 組合）以前都會令成頁
   橫向滾動。用 overflow-x:clip（唔用 hidden）因為 clip 唔會建立捲動容器，
   position:sticky 照樣黐得到。
   --------------------------------------------------------------------------- */
html,body{overflow-x:clip;}

/* 長文字區一律容許斷字（中文本身可以斷，呢啲係防拉丁長字／URL／數式）。
   ⚠️ 刻意唔包 .q-svg（佢本身已有 overflow-x:auto，要保留橫向捲 SVG）。 */
.q-prompt,
.ans-line,
.explain-box,
.q-opt,
.q-passage,
.muted,
.toast,
.tray-why,
.person-row-sub,
.notif-item .notif-text,
.own-card,
.own-content{overflow-wrap:break-word;word-break:break-word;}

/* 共用橫向捲動容器：由 components.js 嘅 UI.wrapScroller()／UI.scrollIfWide()
   加喺內嵌 <table> 外面（class 名係 A3 嘅契約，呢度只提供樣式）。
   overscroll-behavior-x:contain 令喺表上面左右掃時唔會連帶拉動成頁。 */
.table-scroll{
  max-width:100%;min-width:0;
  overflow-x:auto;
  -webkit-overflow-scrolling:touch;
  overscroll-behavior-x:contain;
  margin:10px 0;
}
.table-scroll::-webkit-scrollbar{height:6px;}
.table-scroll::-webkit-scrollbar-thumb{background:rgba(15,23,42,.18);border-radius:99px;}

/* table.fee 原本 padding:6px 22px + 16.5px 字（style.css:344-346）。實測兩欄種子
   收費表喺 360px 容器內只有約 179px（cell 內容會自動換行），所以唔一定爆；但只
   要有 nowrap／一長串數字，min-content 就會超過卡片可用闊度。呢兩條只喺窄螢幕
   收窄內邊距（360px：4px 8px、14.5px 字；480px：5px 10px、15px 字），令佢有更
   多餘裕。原本 table.fee 嘅 rule 完全冇郁。
   （實測：6 欄 nowrap 表 501px 喺 360px 之下只喺 .table-scroll 內橫捲，
     成頁 documentElement.scrollWidth 仍然 = 360px。） */
@media (max-width:480px){
  .table-scroll table.fee th,
  .table-scroll table.fee td{padding:5px 10px;font-size:15px;}
}
@media (max-width:360px){
  .table-scroll table.fee th,
  .table-scroll table.fee td{padding:4px 8px;font-size:14.5px;}
}

/* ---------------------------------------------------------------------------
   T3（P0-3）safe-area（iPhone 動態島／手勢列／橫向瀏海）
   index.html 第 5 行 viewport 已加 viewport-fit=cover，呢度配合 env()。
   ⚠️ 一定要寫 fallback（env(x,0px)），非瀏海機／桌面唔會多咗空位。
   --------------------------------------------------------------------------- */
#app-nav{
  /* ⚠️ 用 10px 唔係 8px：:621 嘅 padding:8px… 之後被 :751 嘅
     padding:10px … 0 覆寫（底部 0，tab 貼齊底邊），所以實際生效係 10px。
     寫 8px 會令桌面 nav 靜靜矮 2px。 */
  padding-top:calc(10px + env(safe-area-inset-top,0px));
  /* 橫向（landscape）時左右瀏海：保留原本 max(12px,置中留白) 再加安全區 */
  padding-left:calc(max(12px, (100vw - 900px) / 2) + env(safe-area-inset-left,0px));
  padding-right:calc(max(12px, (100vw - 900px) / 2) + env(safe-area-inset-right,0px));
}

/* nav 高度：實測 51px = padding-top 10px + nav-item 40px + border 1px
   （padding-bottom 係 0，:751）。加入 T5 嘅 nav-item min-height:44px 之後
   會變 55px。style.css:635 寫 72px、:701 後寫覆蓋成 70px → 實際生效 70px，
   加咗 safe-area 之後 nav 高 55px + inset，所以 #app 跟同一條式一定夠位。 */
body.has-nav #app{padding-top:calc(70px + env(safe-area-inset-top,0px));}

.tray{padding-bottom:env(safe-area-inset-bottom,0px);}
#toast-root{bottom:calc(32px + env(safe-area-inset-bottom,0px));}

/* 作答頁冇 nav，進度卡 sticky top:12px（style.css:1097）→ 補安全區。
   有 nav 嘅頁面同時由 64px（style.css:765）跟返 nav 實際高度。 */
body:not(.has-nav) .exam-progress{top:calc(12px + env(safe-area-inset-top,0px));}
body.has-nav .exam-progress{top:calc(64px + env(safe-area-inset-top,0px));}

/* 計時器（fixed top:16 right:16，style.css:279-280）。
   ⚠️ A2 會將佢搬入進度卡做 .exam-timer-inline（position:static），
   到時 top／right 自然失效，呢兩條只係未搬之前嘅保險。 */
.exam-timer{
  top:calc(16px + env(safe-area-inset-top,0px));
  right:calc(16px + env(safe-area-inset-right,0px));
}

.own-drawer{padding-top:env(safe-area-inset-top,0px);}

/* ---------------------------------------------------------------------------
   T4（P1-2 CSS 部分）底部緩衝、層級、A2 契約
   --------------------------------------------------------------------------- */

/* 底部緩衝：80px（style.css:700 後寫覆蓋咗 :65 嘅 92px）→ 120px，令最尾一題
   同 sticky 交卷巴／tray 之間有足夠空間。
   ⚠️ owner 控制台唔用 #app 呢條（body.page-owner #app 特異度更高，維持原本
   60px／≤700px 40px），因為 owner 頁冇 sticky 交卷巴。 */
#app{padding-bottom:120px;}

/* toast（z-index 200）同 tray（z-index 210）會疊：tray 彈出時 toast 被蓋。
   揀「提高 toast z-index」而唔係「再加 bottom 偏移」嘅理由：
   ① toast 係短暫提示（自動消失），蓋住 tray 幾秒冇功能損失；
   ② 加 bottom 偏移就要寫死 tray 高度，tray 內容會換行（.tray-txt flex-wrap），
      高度唔固定，寫死數會喺窄機失準。 */
#toast-root{z-index:220;}

/* A2 契約（作答頁：進度卡變一條 row，計時器做 flex item）。
   ⚠️ 用 :has(.exam-timer-inline) 守住：A2 未落地之前，.exam-progress 裏面仍然
   係 [progTop][segBar] 兩層 block，直接加 display:flex 會令兩者並排而爆版；
   加咗守門之後，只有真正有 .exam-timer-inline 嘅新結構先會變 row。 */
.exam-progress:has(.exam-timer-inline){
  display:flex;align-items:center;gap:10px;flex-wrap:nowrap;
}
.exam-progress:has(.exam-timer-inline) .seg-bar{flex:1 1 auto;min-width:0;}
.exam-timer-inline{
  position:static;top:auto;right:auto;
  box-shadow:none;
  padding:6px 14px;
  font-size:17px;
  flex:none;
  white-space:nowrap;
}

/* ---------------------------------------------------------------------------
   T5（P2-1）Touch target 一律 ≥44×44
   取捨：真控件（.btn-sm／.tab／.bell／.count-btn／.grade-pill）用 min-height／
   min-width 44px **全尺寸生效** —— 桌面每個只係高 3–6px（原本 38–41px），
   唔會「笨重」；反過來只喺 pointer:coarse 生效就冇人喺桌面睇得到、亦驗唔到。
   另外兩個（.landing-dot／.due-link／.m-advlink）：
   ① .due-link／.m-advlink 係純文字 link，撐到 44px 會推走隔籬元素 → 用
      inline-flex + min-height（唔加 padding，闊度唔變）；
   ② .landing-dot 係 carousel 指示點，24→44px cell 會令點距由 30px 變 44px，
      桌面（有左右箭咀）睇落會鬆散 → 只喺 pointer:coarse 放大（見 T7 段）。
   --------------------------------------------------------------------------- */
.btn-sm{min-height:44px;}
/* ⚠️ !important 係故意：profile.js:422 對 .tab 寫死 inline min-height:40px，
   inline 優先度高過任何選擇器（同 style.css:1415 用 !important 蓋 inline font-size
   係同一個理由）。冇 !important 嘅話，個人檔案頁嘅分頁會停留喺 40px。 */
.tab{min-height:44px !important;}
.count-btn{min-height:44px;}
.grade-pill{min-height:44px;}
/* 601–1023px（iPad／Tab S／Redmi Pad 直向）係 label 版 nav-item，
   高度只有 40px（:751 padding 9px + 13.5px 字）；呢度補到 44px。
   nav 總高由 51px → 55px，仍然細過 #app 嘅 70px padding-top。 */
#app-nav .nav-item{min-height:44px;}
.bell{
  min-width:44px;min-height:44px;
  display:inline-flex;align-items:center;justify-content:center;
}
.due-link{display:inline-flex;align-items:center;min-height:44px;}
.m-advlink{display:inline-flex;align-items:center;min-height:44px;}

/* ---------------------------------------------------------------------------
   T6（P2-2／P2-3／P2-4）平板同細機
   --------------------------------------------------------------------------- */

/* P2-2 頂部 nav 601–1023px 嘅右側 fade mask ── **決定唔做**（用實測數字判斷）：
   學生 5 個 nav item（主頁／我的檔案／朋友／團隊／登出）@601px 以上：
   padding 9px×2 + icon 18px + gap 6px + 字（2–4 個中文字 27–54px）
   → 實測「主頁」89px、「我的檔案」約 116px，5 項約 472px；
     加 gap 8×4 = 32 同 nav 左右 12×2 = 24 → 約 528px < 601px（最窄可達寬度）。
   實測 #app-nav：601px（586 vs 601）、768px（753 vs 768）scrollWidth ===
   clientWidth，溢出 = 0；1023px 更鬆（owner 2 項／家長 3 項更短）。
   既然 601–1023px 完全冇溢出，fade mask 只會係視覺噪音（永遠唔會 fade 走啲
   睇唔到嘅嘢），所以唔加。真正需要橫捲嘅 ≤600px 已經轉 icon-only（≈301px
   @360px、271px @320px，見 :1751-1756 註釋），同樣 0 溢出。 */

/* P2-3 .m-seg 三格喺 ≤480px 好逼（360px 每格約 104px，sub 兩行高低不一）→
   改一欄直排。480–600px 維持三欄。
   ⚠️ .m-seg-2（派卷／設定兩分頁）唔跟：兩格喺 360px 每格約 158px，足夠；
   兩粒掣垂直排反而浪費高度。所以用 :not(.m-seg-2) 排除。 */
@media (max-width:480px){
  .m-seg:not(.m-seg-2){grid-template-columns:1fr;}
}

/* P2-4 標題孤行：Chromium／Safari 支援 text-wrap:balance，Firefox 會靜靜忽略
   （唔會壞版）。只做 h1,h2（h3／h4 短標題冇需要）。 */
h1,h2{text-wrap:balance;}

/* ---------------------------------------------------------------------------
   T7（P2-6）Landing 細機
   --------------------------------------------------------------------------- */

/* ① 圖區高度：原本只有 ≤380px 收 28vh（style.css:1656-1658），細機（≤640px）
   一樣一屏放唔落，所以提前到 640px。後寫者生效，覆寫 ≤1023px 嘅 34vh。 */
@media (max-width:640px){
  .landing-sales{height:28vh;height:28dvh;min-height:120px;}
}

/* ② 登入卡捲動提示：≤1023px 上下排列時，登入卡係 flex:1 + overflow-y:auto。
   喺容器底部 26px 加 fade（mask 跟容器 border-box，唔跟內容捲動）＝「下面仲有」。
   ⚠️ 同時將 padding-bottom 加到 34px：捲到底時最後 26px 係空 padding，
   唔會令「登入」掣長期處於半透明狀態。內容短（唔使捲）時底部係空白白底，
   fade 睇唔到，零視覺雜訊。
   ⚠️ A4 已經喺 landing.js:218 用 inline style 落咗一條 16px 版本嘅同款 mask
   （inline 優先度較高，會蓋過呢一條）。兩者唔會疊：實際生效係 A4 那條，
   而呢條係 CSS fallback（landing.js 改動／inline 拿掉時仍然有提示）。
   我加嘅 padding-bottom:34px 反而提高咗安全性 —— 34px > A4 嘅 16px fade 區，
   即係捲到底時 CTA 掣完全唔會落入漸淡範圍（實測 375×667 scrollable 89px）。 */
@media (max-width:1023px){
  .landing-login{
    padding-bottom:34px;
    -webkit-mask-image:linear-gradient(180deg,#000 0,#000 calc(100% - 26px),transparent 100%);
    mask-image:linear-gradient(180deg,#000 0,#000 calc(100% - 26px),transparent 100%);
  }
}

/* ③ .landing-page 加 safe-area（fixed inset:0；box-sizing:border-box，加 padding
   唔會撐闊）。直向畀頂部動態島、橫向畀左右瀏海。 */
.landing-page{
  padding-top:env(safe-area-inset-top,0px);
  padding-left:env(safe-area-inset-left,0px);
  padding-right:env(safe-area-inset-right,0px);
}

/* ④ carousel 指示點：只喺觸控裝置放大點擊格（視覺 8px 圓點不變）。
   24→44px cell 會令點距 30px → 44px，配 gap:0 令 hit box 相鄰但唔重疊。 */
@media (pointer:coarse){
  .landing-dot{width:44px;height:44px;}
  .landing-dots{gap:0;}
}

/* ---------------------------------------------------------------------------
   T8（P3）美學收尾
   ① 立體下壓 3D 掣：動畫係 transform，喺低端機 hover／active 時先開
      will-change:transform，等瀏覽器早一格上 GPU 層（避免逐格 repaint）。
      ⚠️ 只喺 hover／focus-visible 開（唔係長開）——長開會令每粒掣都各自
      建立合成層，owner 控制台幾十粒掣反而更食記憶體。
      ⚠️ will-change 唔改變任何視覺，原有 hover／active 陰影效果完全不變。
   --------------------------------------------------------------------------- */
body.page-owner button:not(:disabled):hover,
body.page-owner button:not(:disabled):focus-visible,
.btn:hover,
.btn:focus-visible,
.choice:hover,
.choice:focus-visible,
.pick-card:hover,
.m-child:hover,
.m-seg-btn:hover,
.grade-pill:hover{will-change:transform;}


/* ===========================================================================
   v5.9-fix59（2026-10-03）：三個獨立修正。全部檔尾 append，上面既有 rule 一律不改。
   （改動前的 rule 只被「後寫者勝」覆蓋，冇任何既有宣告被刪或改寫。）
   =========================================================================== */

/* ---------------------------------------------------------------------------
   ① T1（P1）：全形空格（U+3000）長 run 令 .q-passage 在 320px 靜默溢出 18px
   ---------------------------------------------------------------------------
   真因（Chromium 實測，非推測）：
   U+3000 IDEOGRAPHIC SPACE 屬 CSS 的 "other space separator"，只有 U+0020 與
   U+0009 會在 white-space:normal／pre-line 之下被合併；U+3000 一律原樣保留，
   而且 white-space:pre-line 之下瀏覽器**不會在這個 run 中間開斷行機會**。
   涉事段落的 11c 短信格式如下（真資料，全文 131 字）：
       美儀：\n　　謝謝你昨天借給我的故事書…\n　　　…（19 個 U+3000）…子軒\n
   → 18 個 U+3000 × 15.5px = 279px 的一條「死線」，內容盒只有 206px
     （320px 機寬 − 卡片內距），所以 body.scrollWidth 338 > 320。
   實測已排除（全部無效，body.scrollWidth 仍是 338）：
     overflow-wrap:break-word／anywhere、word-break:break-word／normal／break-all。
   實測有效：white-space:pre-wrap（338 → 320），或 line-break:anywhere。
   ⚠️ 選 pre-wrap 而不用 line-break:anywhere 的原因（都有數字）：
     · pre-wrap 完全保留原有中英文斷行位置（實測行首字 爺／有／半 與英文行首
       The／over／runs 與 pre-line 一模一樣），也不會丟失中文標點的禁則處理；
     · line-break:anywhere 會在英文詞中間斷開（實測 over → 「er」開頭一行）
       並且把斷行機會擴散到所有字元，對英文科內容是明顯回歸。
   ⚠️ 不用 overflow-x:auto（垂直長文不應該變橫捲）。
   一併覆蓋同樣宣告 white-space:pre-line 的長文容器（同一真因、同一風險）：
     .q-prompt（style.css:333）、.explain-box（style.css:407）、
     .section-head .section-instructions（style.css:321）。
   pre-wrap 與 pre-line 的差別只在「U+0020 連續空格會否合併」：全資料庫 4694 個
   文字欄位之中只有 4 個含連續 U+0020（而且都在英文字句中間，多顯示一個空格），
   影響可忽略；49 個欄位含 U+3000，是本修正真正處理的對象。
   --------------------------------------------------------------------------- */
.q-passage,
.q-prompt,
.explain-box,
.section-head .section-instructions{white-space:pre-wrap;}

/* ---------------------------------------------------------------------------
   ② T2（P2／P3）：Touch target 一律 ≥44×44 熱區（視覺尺寸盡量不變）
   ---------------------------------------------------------------------------
   策略同 v5.9 的 T5 段一致：用 min-height／min-width／inline-flex 撐大命中區，
   不用 transform:scale、不用負 margin。真控件一律全尺寸生效（桌面只高幾 px）。
   ⚠️ .tab 早在 v5.9 已用 min-height:44px !important（style.css:2005），本段不動它。
   --------------------------------------------------------------------------- */

/* 基本款 .btn：本體 42px（padding 13px×2 + 16px 行盒）→ 44px。
   .btn-lg 本來 48px、.btn-sm 已由 v5.9 拉到 44px，皆不受影響。
   交卷巴用的是 .btn.btn-lg（48px）、上一頁／下一頁用 .btn-sm，故作答頁不受影響。 */
.btn{min-height:44px;}

/* 家長首頁子女卡：40px → 44px（.m-child 本身 inline-flex，加 min-height 即可）。 */
.m-child{min-height:44px;}

/* Owner 控制台「☰ 選單」：41px → 44px。 */
.own-menu-btn{min-height:44px;}

/* Owner 抽屜「✕」：35.9×31 → 44×44（抽屜內部，不影響任何版面）。 */
.own-drawer-x{min-width:44px;min-height:44px;}

/* 登入頁「系統管理員入口」：103×22 → 103×44。
   ⚠️ 保留原本 display:block（靠 margin:34px auto 0 置中，父層 .auth-wrap 冇
   text-align:center，改成 inline-flex 會靠左）；改用 line-height 令單行文字垂直置中，
   闊度不變。 */
.owner-entry{min-height:44px;line-height:44px;}

/* 登入頁／管理員登入頁的純文字連結（「註冊」、「← 返回一般用戶登入」）：
   30×20 → ≥44×44。.auth-alt 本身 text-align:center，inline-flex 仍然居中；
   vertical-align:middle 避免把同行的「未有帳號？」推歪。 */
.auth-alt a{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:44px;min-height:44px;vertical-align:middle;
}

/* 個人檔案／子女檔案「我的團隊」隊名連結（.profile.js 產生的 a，無 class，href 一定是
   #/team/<id>）：85×26.9 → ≥44 高。同頁的「進入團隊瀏覽 →」本身是 .btn-sm（已 44px），
   套用同一條只會維持 44px。 */
a[href^="#/team/"]{display:inline-flex;align-items:center;min-height:44px;}

/* 頂部導覽 5 個項目：42×44 → 44×44（只有闊度不足）。只加 min-width，不動 padding，
   所以 ≤360px 的 icon 收窄規則（style.css:1760-1763）照舊生效。
   320px 是否放得落：見下方實測（5 項總闊 + gap + 左右 padding 仍 < 320）。 */
#app-nav .nav-item{min-width:44px;}

/* Landing 左右箭咀：桌面（pointer:fine）保持 38px（設計要求，不變笨重）；
   觸控裝置才拉到 44×44。 */
@media (pointer:coarse){
  .landing-arrow{width:44px;height:44px;min-width:44px;min-height:44px;}
}

/* ---------------------------------------------------------------------------
   ③ T3（P3）：.tab 字重不一致
   ---------------------------------------------------------------------------
   .tab 基本款（style.css:143）寫死 font-weight:500，.tab.active（:148）是 700；
   實測（360px）學生首頁 #/ 與 #/teams 的非作用中 .tab computed font-weight 都是 500，
   作用中都是 700。這裡把基本款統一成 700，跟 .tab.active 一致（不影響 .active 任何樣式）。
   --------------------------------------------------------------------------- */
.tab{font-weight:700;}


/* ============================================================================
   v6.0（2026-10-03）：9 組新 UI class 契約（T1–T9，供其他 agent 嘅功能使用）
   ----------------------------------------------------------------------------
   依據 COMMENTS_REVIEW_2026-10-03.md（Comment 3／4／5／6／8／9／10）逐項提供樣式。
   ⚠️ 本段全部追加於檔案末端（原本 2205 行）。上面既有 rule 一個字都冇改、冇
      reformat；一律靠「後寫者生效」覆寫。唯一嘅覆寫只喺本段**新建**嘅 media query
      之內（而且只覆寫本段自己嘅 class，冇覆寫任何舊 class 嘅舊值）。
   ⚠️ 純 CSS，冇引入任何 framework／library。
   ⚠️ 冇用 !important（`.tab` 嗰處 min-height:44px 係 v5.9 遺留，與本段無關）。
   ⚠️ 冇重新定義 body 嘅 font-weight／line-height（v5.9 已定案 500／1.58）。
   ⚠️ 設計 token 一律 var(--*) 並寫 fallback（--radius 呢個名唔存在，用 --card-radius）。
   ⚠️ 互動元素熱區一律 ≥44×44：.hw-go／.mf-pager-btn／.q-flag／.team-hero-up／
      .master-go（視覺尺寸靠 padding／min-width／min-height 撐大，唔用 transform）。
   ⚠️ 三尺寸斷點：desktop（預設 >1024）／tablet（≤1024、≤760）／mobile（≤430），
      另按需要加 ≤600（跟現有 .mf-*／.exam-pager 手機橫向微調嘅斷點習慣）。
   ============================================================================ */


/* ===========================================================================
   T1（Comment 3）學生「待做功課」卡
   class 契約：.hw-card／.hw-head／.hw-count／.hw-row／.hw-title／.hw-sub／.hw-go
   ---------------------------------------------------------------------------
   一行式設計：桌面／平板每行 = 卷名＋派卷人＋掣同一行；≤600px 自動換行成
   「卷名（＋派卷人）一行、掣獨佔一行」。
   ⚠️ .hw-title 唔可以壓縮（唔用 ellipsis），長卷名一律換行顯示全文。
   =========================================================================== */

.hw-card{
  position:relative;
  /* 冇 .hw-card 專屬 token，全部借卡片代幣，保證同 .card 同一個視覺語言 */
  background:var(--card,#fff);
  border:1px solid var(--card-border,rgba(226,232,240,.9));
  border-radius:var(--card-radius,16px);
  box-shadow:var(--card-shadow,0 1px 2px rgba(15,23,42,.04),0 6px 16px rgba(15,23,42,.05));
  padding:16px 18px 14px;
  margin-bottom:var(--gap,14px);
  min-width:0;
}
/* 頂部 3px 品牌漸變條：一眼睇得出係「要做嘢」嘅卡，唔會同普通 .card 混淆。
   用 ::before 而唔用 border-top，係為咗唔改變盒模型高度（避免同 .card 差 2px）。 */
.hw-card::before{
  content:"";
  position:absolute;left:0;right:0;top:0;height:3px;
  border-radius:var(--card-radius,16px) var(--card-radius,16px) 0 0;
  background:var(--aurora,linear-gradient(135deg,#2A5CE8 0%,#3B6FF5 100%));
  pointer-events:none;
}

.hw-head{
  display:flex;align-items:center;gap:8px;
  min-width:0;
  margin:0 0 8px;
}
.hw-title{
  min-width:0;
  margin:0;
  font-size:var(--fs-md,16.5px);
  font-weight:900;
  line-height:1.3;
  color:var(--ink,#0F172A);
  overflow-wrap:break-word;
  word-break:break-word;
}
/* 行內嘅卷名比卡標題細一級、輕一級（仲係 800，唔會虛） */
.hw-row .hw-title{
  flex:1 1 auto;
  font-size:var(--fs-base,15px);
  font-weight:800;
  line-height:1.35;
}
.hw-sub{
  min-width:0;
  margin-top:2px;
  font-size:var(--fs-xs,12px);
  font-weight:700;
  line-height:1.45;
  color:var(--ink-soft,#475569);
  overflow-wrap:break-word;
  word-break:break-word;
}

/* 數量 badge：品牌色底白字，最小 22px（單數字 = 正圓；多位數字自動長成藥丸） */
.hw-count{
  flex:none;
  display:inline-flex;align-items:center;justify-content:center;
  min-width:22px;height:22px;padding:0 6px;
  border-radius:var(--radius-pill,999px);
  background:var(--brand,#2A5CE8);
  color:#fff;
  font-size:var(--fs-xs,12px);
  font-weight:900;
  line-height:1;
  font-variant-numeric:tabular-nums;
  letter-spacing:0;
  box-sizing:border-box;
}

.hw-row{
  display:flex;align-items:center;gap:4px 10px;
  padding:10px 2px;
  min-width:0;
}
/* 用相鄰兄弟而唔用 :first-child，避免 JS 改 DOM 次序時第一行無端多一條線 */
.hw-row + .hw-row{border-top:1px solid var(--line,#E2E8F0);}
/* 卷名／細字嘅包裝層（div／span）食晒剩餘闊度，令 .hw-go 靠右；
   同時 min-width:0 係 flex 子項可以真正縮到細過內容闊度嘅必要條件。 */
.hw-row > div,
.hw-row > span,
.hw-row > p{flex:1 1 auto;min-width:0;}

.hw-go{
  flex:none;
  margin-left:auto;
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  min-width:44px;min-height:44px;         /* 熱區 ≥44×44 */
  padding:9px 18px;
  font-family:inherit;
  font-size:var(--fs-sm,13.5px);
  font-weight:800;
  line-height:1.2;
  color:#fff;
  background:var(--brand,#2A5CE8);
  border:none;
  border-radius:var(--radius-pill,999px);
  box-shadow:0 3px 0 0 var(--brand-dark,#1E46B8);
  cursor:pointer;
  text-decoration:none;
  white-space:nowrap;
  transition:transform .06s ease, box-shadow .06s ease, background .15s ease;
}
.hw-go:hover{background:var(--brand-dark,#1E46B8);text-decoration:none;}
.hw-go:active{transform:translateY(3px);box-shadow:0 0 0 0 var(--brand-dark,#1E46B8);}
.hw-go:focus-visible{outline:2px solid var(--brand,#2A5CE8);outline-offset:2px;}

/* --- T1 三尺寸 --- */
@media (max-width:760px){
  .hw-card{padding:14px 15px 12px;}
  .hw-row{padding:9px 2px;}
}
@media (max-width:600px){
  /* 窄螢幕：換行成兩行 —— 卷名（＋派卷人）獨佔一行、掣獨佔另一行。
     換行靠 flex-wrap，唔靠縮窄卷名，所以長標題一定顯示全文。 */
  .hw-row{flex-wrap:wrap;row-gap:8px;}
  .hw-row > div,
  .hw-row > span,
  .hw-row > p{flex:1 1 100%;}
  .hw-go{flex:1 1 100%;margin-left:0;padding:11px 18px;}
}
@media (max-width:430px){
  .hw-card{padding:13px 13px 11px;}
  .hw-head{gap:6px;}
  .hw-title{font-size:var(--fs-base,15px);}
  .hw-count{min-width:22px;height:22px;padding:0 5px;}
}


/* ===========================================================================
   T2（Comment 6）朋友清單分頁 pager
   class 契約：.mf-pager／.mf-pager-btn／.mf-pager-info
   ---------------------------------------------------------------------------
   視覺對齊現有 .exam-pager（flex 置中、gap:10px、wrap、margin:6px 0 14px）；
   ⚠️ 上面 .exam-pager 本身完全冇改，呢度只係一組同名數值嘅新 class。
   每個掣熱區 ≥44×44；≤600px 字級同內距收一級（跟 review 要求）。
   =========================================================================== */

.mf-pager{
  display:flex;align-items:center;justify-content:center;
  gap:10px;flex-wrap:wrap;
  margin:6px 0 14px;
  min-width:0;
}
.mf-pager-info{
  font-size:var(--fs-sm,13.5px);
  font-weight:800;
  color:#64748B;
  font-variant-numeric:tabular-nums;
  white-space:nowrap;
}
.mf-pager-btn{
  display:inline-flex;align-items:center;justify-content:center;gap:4px;
  min-width:44px;min-height:44px;         /* 熱區 ≥44×44 */
  padding:8px 14px;
  font-family:inherit;
  font-size:var(--fs-sm,13.5px);
  font-weight:800;
  line-height:1.2;
  color:var(--ink,#0F172A);
  background:var(--card,#fff);
  border:1px solid var(--line,#E2E8F0);
  border-radius:12px;
  cursor:pointer;
  white-space:nowrap;
  text-decoration:none;
  transition:background .15s ease, border-color .15s ease, color .15s ease;
}
.mf-pager-btn:hover{background:var(--surface,#F1F5F9);border-color:#CBD5E1;text-decoration:none;}
.mf-pager-btn:active{background:var(--brand-soft,#EEF3FE);}
.mf-pager-btn:focus-visible{outline:2px solid var(--brand,#2A5CE8);outline-offset:2px;}
.mf-pager-btn:disabled,
.mf-pager-btn[disabled]{
  color:#94A3B8;background:var(--surface,#F1F5F9);border-color:var(--line,#E2E8F0);
  cursor:not-allowed;box-shadow:none;
}
/* 現正頁（JS 用 aria-current 或 .on 都可以） */
.mf-pager-btn[aria-current="page"],
.mf-pager-btn.on{
  background:var(--brand,#2A5CE8);color:#fff;border-color:var(--brand,#2A5CE8);
}
.mf-pager-btn[aria-current="page"]:hover,
.mf-pager-btn.on:hover{background:var(--brand-dark,#1E46B8);border-color:var(--brand-dark,#1E46B8);}

@media (max-width:760px){
  .mf-pager{gap:8px;}
}
@media (max-width:600px){
  .mf-pager{gap:6px;margin:4px 0 12px;}
  .mf-pager-info{font-size:var(--fs-xs,12px);}
  .mf-pager-btn{padding:8px 12px;font-size:var(--fs-xs,12px);}
}
@media (max-width:430px){
  .mf-pager{gap:5px;}
  .mf-pager-btn{min-width:44px;padding:8px 10px;}
}


/* ===========================================================================
   T3（Comment 5）作答模式每題 Flag 掣
   class 契約：.q-flag（+ .q-flag.on）
   ---------------------------------------------------------------------------
   放喺 .q-head 尾（.q-marks 之後，靠 .q-marks 嘅 margin-left:auto 推去最右）。
   ⚠️ flex:none 係硬性要求：唔准影響 .q-head 嘅換行／壓縮題號。
   視覺低調：預設透明底＋透明邊＋灰 icon；hover／focus 先出現淡底。
   熱區 ≥44×44 用 padding＋min-width/min-height 撐（唔用 transform、唔用負 margin）。
   ⚠️ 已知取捨：撐到 44px 會令 .q-head 由約 24px 變 44px（每題高約 20px）。
      呢個係「熱區 44」同「header 高度」之間嘅必然取捨，review 明確要求前者。
   =========================================================================== */

.q-flag{
  flex:none;                              /* 硬性：唔參與壓縮、唔影響換行 */
  align-self:center;                      /* 父層 .q-head 係 align-items:baseline，
                                             加咗 min-height 之後 baseline 會怪，
                                             喺自己身上置中，唔使改 .q-head */
  display:inline-flex;align-items:center;justify-content:center;gap:4px;
  min-width:44px;min-height:44px;         /* 熱區 ≥44×44 */
  padding:6px 10px;
  margin:0;
  font-family:inherit;
  font-size:var(--fs-sm,13.5px);
  font-weight:800;
  line-height:1;
  color:#94A3B8;                          /* 低調灰 */
  background:transparent;
  border:1px solid transparent;
  border-radius:12px;
  cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  transition:background .15s ease, color .15s ease, border-color .15s ease;
}
.q-flag:hover{
  background:var(--surface,#F1F5F9);
  border-color:var(--line,#E2E8F0);
  color:var(--ink-soft,#475569);
}
.q-flag:focus-visible{outline:2px solid var(--brand,#2A5CE8);outline-offset:2px;}
/* 已 flag：coral 底白字（review 提供嘅兩個選項之一，coral 對「有問題」語意更準，
   亦比白字放金色底嘅對比度高） */
.q-flag.on,
.q-flag[aria-pressed="true"]{
  background:var(--coral,#F43F5E);
  border-color:var(--coral,#F43F5E);
  color:#fff;
}
.q-flag.on:hover,
.q-flag[aria-pressed="true"]:hover{
  background:var(--coral-dark,#C42D48);
  border-color:var(--coral-dark,#C42D48);
  color:#fff;
}

@media (max-width:760px){
  .q-flag{padding:6px 8px;}
}
@media (max-width:430px){
  /* 窄機：icon＋文字可能放唔落，靠 flex:none + min-width 保持 44×44 唔變形 */
  .q-flag{min-width:44px;min-height:44px;padding:6px 8px;font-size:var(--fs-xs,12px);}
}


/* ===========================================================================
   T4（Comment 8）團隊 Hero（banner ＋ logo）
   class 契約：.team-hero／.team-hero-bg／.team-hero-scrim／.team-hero-body／
              .team-hero-logo／.team-hero-name／.team-hero-up
   ---------------------------------------------------------------------------
   疊層：.team-hero-bg（z0，絕對定位鋪滿）→ .team-hero-scrim（z1，由下而上漸變）
        → .team-hero-body（z2，左下落 logo＋隊名＋統計）／.team-hero-up（z3，右上）。
   ⚠️ .team-hero-bg 契約高度 160px；用 min-height:100% 令 hero 因內容變高時
      相片仍然鋪滿（min-height 大過 height 時以 min-height 為準），唔會露出底色。
   ⚠️ 冇 banner 時 JS 用原有樣式（唔關本段事），但 .team-hero 自己都有漸變底 +
      min-height，所以就算 JS 咩都唔畫都唔會空白一片。
   =========================================================================== */

.team-hero{
  position:relative;
  isolation:isolate;                      /* 令內部 z-index 唔會漏出外面 */
  overflow:hidden;                        /* 令 banner 相被卡角裁切 */
  border-radius:var(--card-radius,16px);
  background:var(--aurora-wide,linear-gradient(120deg,#2A5CE8 0%,#3B6FF5 55%,#6D8CF0 100%));
  box-shadow:var(--card-shadow,0 1px 2px rgba(15,23,42,.04), 0 6px 16px rgba(15,23,42,.05));
  color:#fff;
  min-height:160px;                       /* 冇內容／冇相都唔會塌 */
  margin-bottom:var(--gap,14px);
  min-width:0;
}
.team-hero-bg{
  position:absolute;left:0;top:0;
  z-index:0;
  display:block;
  width:100%;
  height:160px;                           /* desktop 契約值 */
  min-height:100%;                        /* hero 更高時自動鋪滿 */
  object-fit:cover;
  object-position:center;
  border:0;
  pointer-events:none;
}
.team-hero-scrim{
  position:absolute;left:0;right:0;top:0;bottom:0;
  z-index:1;
  background:linear-gradient(180deg,
    rgba(15,23,42,0) 0%,
    rgba(15,23,42,.06) 34%,
    rgba(15,23,42,.44) 66%,
    rgba(15,23,42,.80) 100%);
  pointer-events:none;
}
.team-hero-body{
  position:relative;
  z-index:2;
  display:flex;flex-wrap:wrap;
  align-items:flex-end;align-content:flex-end;
  justify-content:flex-start;
  gap:4px 14px;
  min-height:160px;
  padding:16px 18px;
  box-sizing:border-box;
  min-width:0;
  color:#fff;
}
.team-hero-body > *{min-width:0;}
.team-hero-body .muted,
.team-hero-body small{color:rgba(255,255,255,.86);}
/* 統計行若果用 .tag 標籤，喺深色 hero 上轉成白玻璃底，避免淺底淺字 */
.team-hero-body .tag{
  background:rgba(255,255,255,.22);
  color:#fff;
  border:1px solid rgba(255,255,255,.34);
}

.team-hero-logo{
  flex:none;
  align-self:flex-end;
  display:block;
  width:64px;height:64px;                 /* desktop 契約值 */
  border-radius:16px;
  background:var(--card,#fff);
  object-fit:cover;
  border:2px solid rgba(255,255,255,.92);
  box-shadow:0 3px 12px rgba(15,23,42,.30);
  box-sizing:border-box;
}
.team-hero-name{
  flex:1 1 auto;
  min-width:0;
  font-size:var(--fs-lg,18px);
  font-weight:900;
  line-height:1.3;                        /* 契約：1.3 倍行高 */
  color:#fff;
  text-shadow:0 1px 3px rgba(15,23,42,.55);
  overflow-wrap:break-word;
  word-break:break-word;
}

/* 團長先見到嘅上載掣：hero 右上角，半透明白玻璃底 */
.team-hero-up{
  position:absolute;top:10px;right:10px;
  z-index:3;
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  min-width:44px;min-height:44px;         /* 熱區 ≥44×44 */
  max-width:calc(100% - 20px);
  padding:8px 14px;
  font-family:inherit;
  font-size:var(--fs-sm,13.5px);
  font-weight:800;
  line-height:1.2;
  color:#fff;
  background:rgba(255,255,255,.24);
  border:1px solid rgba(255,255,255,.52);
  border-radius:var(--radius-pill,999px);
  -webkit-backdrop-filter:blur(6px);
  backdrop-filter:blur(6px);
  text-shadow:0 1px 2px rgba(15,23,42,.45);
  cursor:pointer;
  white-space:nowrap;
  text-decoration:none;
  transition:background .15s ease;
}
.team-hero-up:hover{background:rgba(255,255,255,.36);text-decoration:none;}
.team-hero-up:focus-visible{outline:2px solid #fff;outline-offset:2px;}

/* --- T4 三尺寸：banner 160（desktop）→140（tablet）→120（mobile）；
       logo 64 → 60 → 56；隊名 18 → 16.5 → 15 --- */
@media (max-width:1024px){
  .team-hero{min-height:140px;}
  .team-hero-bg{height:140px;}
  .team-hero-body{min-height:140px;padding:14px 16px;gap:4px 12px;}
  .team-hero-logo{width:60px;height:60px;border-radius:14px;}
  .team-hero-name{font-size:var(--fs-md,16.5px);}
}
@media (max-width:760px){
  .team-hero{min-height:140px;}
  .team-hero-bg{height:140px;}
  .team-hero-body{min-height:140px;}
}
@media (max-width:430px){
  .team-hero{min-height:120px;margin-bottom:var(--gap-sm,10px);}
  .team-hero-bg{height:120px;}
  .team-hero-body{min-height:120px;padding:12px 13px;gap:3px 10px;}
  .team-hero-logo{width:56px;height:56px;border-radius:14px;border-width:2px;}  /* mobile 契約值 */
  .team-hero-name{font-size:var(--fs-base,15px);line-height:1.3;}
  .team-hero-up{top:8px;right:8px;padding:8px 12px;font-size:var(--fs-xs,12px);}
}


/* ===========================================================================
   T5（Comment 8）團隊列表細 logo
   class 契約：.team-logo-sm／.team-logo-emoji
   ---------------------------------------------------------------------------
   兩者都係 28px 圓角方形、垂直置中，可以互換擺喺同一位置（有 logo 用相，
   冇 logo 由 JS 用 emoji fallback）。
   =========================================================================== */

.team-logo-sm{
  flex:none;
  display:inline-block;
  vertical-align:middle;
  width:28px;height:28px;
  border-radius:8px;
  object-fit:cover;
  background:var(--surface,#F1F5F9);
  border:1px solid var(--line,#E2E8F0);
  box-sizing:border-box;
}
.team-logo-emoji{
  flex:none;
  display:inline-flex;align-items:center;justify-content:center;
  vertical-align:middle;
  width:28px;height:28px;
  border-radius:8px;
  background:var(--brand-soft,#EEF3FE);
  color:var(--brand,#2A5CE8);
  border:1px solid var(--line,#E2E8F0);
  box-sizing:border-box;
  font-size:var(--fs-base,15px);
  line-height:1;
  overflow:hidden;
  user-select:none;
}


/* ===========================================================================
   T6（Comment 10）遮罩成員列
   class 契約：.member-masked／.member-tag-leader／.member-tag-friend
   ---------------------------------------------------------------------------
   ⚠️ 上面 .tag 本身完全冇改；下面兩個 tag 係「喺 .tag 基礎上加」——即係就算
      JS 寫成 class="tag member-tag-leader" 或者淨係 member-tag-leader 都一樣樣
      （尺寸用返 .tag 最後生效值：11px／padding 2px 8px／radius 8px／weight 800）。
   =========================================================================== */

.member-tag-leader{
  display:inline-block;
  font-size:11px;font-weight:800;padding:2px 8px;border-radius:8px;white-space:nowrap;
  background:var(--gold-soft,#FFF6E0);
  color:#8A5A00;                          /* 金色系（同 .tag-gold 同色） */
}
.member-tag-friend{
  display:inline-block;
  font-size:11px;font-weight:800;padding:2px 8px;border-radius:8px;white-space:nowrap;
  background:var(--mint-soft,#E7F8F1);
  color:var(--mint-dark,#0B8F63);         /* mint 系（同 .tag-mint 同色） */
}
/* 遮罩姓名：灰色 + 虛線，一眼睇得出係佔位符而唔係真名 */
.member-masked{
  display:inline-block;
  max-width:100%;
  color:#94A3B8;
  font-weight:700;
  letter-spacing:.4px;
  border-bottom:1px dashed #CBD5E1;
  padding-bottom:1px;
  overflow-wrap:break-word;
  word-break:break-word;
}


/* ===========================================================================
   T7（Comment 5）Master「題庫測試」卡
   class 契約：.master-card／.master-row／.master-go
   ---------------------------------------------------------------------------
   金色漸變頂條 + 淡金底，一眼睇得出係「測試區」，同其他卡分得開。
   窄螢幕跟 T1 一樣換行（卷名一行、掣一行），掣熱區 ≥44×44。
   =========================================================================== */

.master-card{
  position:relative;
  background:linear-gradient(135deg,#FFFBEF 0%,#FFFFFF 42%,#FFFFFF 100%);
  border:1px solid #F3E0A8;
  border-radius:var(--card-radius,16px);
  box-shadow:var(--card-shadow,0 1px 2px rgba(15,23,42,.04), 0 6px 16px rgba(15,23,42,.05));
  padding:16px 18px 14px;
  margin-bottom:var(--gap,14px);
  min-width:0;
}
.master-card::before{
  content:"";
  position:absolute;left:0;right:0;top:0;height:3px;
  border-radius:var(--card-radius,16px) var(--card-radius,16px) 0 0;
  background:linear-gradient(90deg,var(--gold,#FFB800) 0%,#F5AE00 52%,var(--brand,#2A5CE8) 100%);
  pointer-events:none;
}
/* 卡標題：若果 JS 沿用 .hw-title／.hw-head 亦可，呢度補一個 master 專屬別名 */
.master-card > h3,
.master-card .master-title{
  margin:0 0 8px;
  min-width:0;
  font-size:var(--fs-md,16.5px);
  font-weight:900;line-height:1.3;
  color:var(--ink,#0F172A);
  overflow-wrap:break-word;word-break:break-word;
}

.master-row{
  display:flex;align-items:center;gap:4px 10px;
  padding:10px 2px;
  min-width:0;
}
.master-row + .master-row{border-top:1px solid #F3E0A8;}
.master-row > div,
.master-row > span,
.master-row > p{flex:1 1 auto;min-width:0;}
.master-row .hw-sub,
.master-row .muted{
  font-size:var(--fs-xs,12px);
  color:var(--ink-soft,#475569);
  overflow-wrap:break-word;word-break:break-word;
}

.master-go{
  flex:none;
  margin-left:auto;
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  min-width:44px;min-height:44px;         /* 熱區 ≥44×44 */
  padding:9px 18px;
  font-family:inherit;
  font-size:var(--fs-sm,13.5px);
  font-weight:800;
  line-height:1.2;
  color:#fff;
  background:var(--brand,#2A5CE8);
  border:none;
  border-radius:var(--radius-pill,999px);
  box-shadow:0 3px 0 0 var(--brand-dark,#1E46B8);
  cursor:pointer;
  text-decoration:none;
  white-space:nowrap;
  transition:transform .06s ease, box-shadow .06s ease, background .15s ease;
}
.master-go:hover{background:var(--brand-dark,#1E46B8);text-decoration:none;}
.master-go:active{transform:translateY(3px);box-shadow:0 0 0 0 var(--brand-dark,#1E46B8);}
.master-go:focus-visible{outline:2px solid var(--brand,#2A5CE8);outline-offset:2px;}

@media (max-width:760px){
  .master-card{padding:14px 15px 12px;}
  .master-row{padding:9px 2px;}
}
@media (max-width:600px){
  .master-row{flex-wrap:wrap;row-gap:8px;}
  .master-row > div,
  .master-row > span,
  .master-row > p{flex:1 1 100%;}
  .master-go{flex:1 1 100%;margin-left:0;padding:11px 18px;}
}
@media (max-width:430px){
  .master-card{padding:13px 13px 11px;}
  .master-card > h3,
  .master-card .master-title{font-size:var(--fs-base,15px);}
}


/* ===========================================================================
   T8（Comment 4／9）Owner「預早出題」＋「內容審查」卡
   class 契約：.own-preg／.own-preg-status／.own-mod-row／.own-mod-hide
   ---------------------------------------------------------------------------
   ⚠️ owner 頁已有大量 .own-* 舊樣式（style.css:642-694、:949-971、:1805-1825），
      本段只**新增**四條 class，冇改任何舊嘅。
   ⚠️ ≤700px 跟返現有 owner mobile media query 嘅精神：卡片 padding 收窄、
      一行容唔落就換行（現有段只覆寫 .own-card 等，本段喺新 media query 內
      為自己嘅新 class 補窄螢幕值）。
   =========================================================================== */

.own-preg{
  display:flex;flex-wrap:wrap;align-items:center;
  gap:10px 14px;
  background:var(--card,#fff);
  border:1px solid var(--line,#E2E8F0);
  border-radius:14px;
  padding:14px 16px;
  box-shadow:var(--card-shadow,0 1px 2px rgba(15,23,42,.04), 0 6px 16px rgba(15,23,42,.05));
  min-width:0;
}
.own-preg + .own-preg{margin-top:var(--gap-sm,10px);}
.own-preg > *{min-width:0;}

/* 上次執行結果：等寬字體 + 細字，狀態色用 owner 現有嘅 ok／bad 慣例 */
.own-preg-status{
  flex:1 1 100%;
  min-width:0;
  margin-top:2px;
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono","Courier New",monospace;
  font-size:var(--fs-xs,12px);
  font-weight:600;
  line-height:1.5;
  color:var(--ink-soft,#475569);
  overflow-wrap:break-word;
  word-break:break-word;
}
.own-preg-status b,.own-preg-status strong{color:var(--ink,#0F172A);font-weight:800;}
.own-preg-status.ok{color:var(--mint-dark,#0B8F63);}
.own-preg-status.bad{color:var(--coral-dark,#C42D48);}
.own-preg-status.warn{color:#8A5A00;}

/* 審查紀錄一行：時間／用戶／類型／動作／原文；容唔落自動換行 */
.own-mod-row{
  display:flex;flex-wrap:wrap;align-items:center;
  gap:4px 10px;
  padding:10px 2px;
  border-bottom:1px solid var(--line,#E2E8F0);
  min-width:0;
}
.own-mod-row:last-child{border-bottom:none;}
.own-mod-row > *{min-width:0;}

/* 原文截短：一定要有 overflow:hidden + nowrap 先出到 ellipsis；
   min-width:0 + flex-basis 令佢可以被壓縮而唔會撐爆卡片。
   ⚠️ 要明確覆寫繼承自 .own-card／.own-content 嘅 word-break:break-word，
      否則 nowrap 之下仍然可能以怪位置斷行。 */
.own-mod-hide{
  flex:1 1 160px;
  min-width:0;
  max-width:100%;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
  overflow-wrap:normal;
  word-break:normal;
  font-size:var(--fs-xs,12px);
  font-weight:600;
  color:var(--ink-soft,#475569);
}

@media (max-width:760px){
  .own-preg{padding:12px 13px;gap:8px 12px;}
  .own-mod-row{gap:4px 8px;padding:9px 2px;}
}
@media (max-width:700px){
  /* 跟返 owner mobile 精神：卡片再收一級；一行容唔落就整行換 */
  .own-preg{padding:12px 12px;border-radius:12px;}
  .own-preg > *{flex:0 1 auto;}
  .own-preg-status{flex:1 1 100%;}
  .own-mod-row{gap:3px 8px;padding:9px 0;}
  .own-mod-hide{flex:1 1 100%;white-space:normal;
    display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;}
}
@media (max-width:430px){
  .own-preg{padding:11px 11px;}
  .own-preg-status{font-size:var(--fs-2xs,10.5px);}
  .own-mod-hide{font-size:var(--fs-2xs,10.5px);}
}


/* ===========================================================================
   T9（Comment 9）守則提示細字
   class 契約：.policy-hint（register／profile／團隊改名 form 下面）
   ---------------------------------------------------------------------------
   12px／var(--ink-soft)／line-height 1.6／margin-top 6px（契約值）。
   窄螢幕唔准變三行以上：全尺寸用 text-wrap:pretty（避免尾行孤字），
   ≤430px 再加 text-wrap:balance（Chromium／Safari 支援；Firefox 靜靜忽略，
   唔會壞版）。句子本身嘅長度由 JS 控制，CSS 只負責唔好因為斷行而多一行。
   =========================================================================== */

.policy-hint{
  margin-top:6px;
  font-size:var(--fs-xs,12px);
  line-height:1.6;
  font-weight:600;
  color:var(--ink-soft,#475569);
  text-wrap:pretty;
  max-width:52em;
  min-width:0;
  overflow-wrap:break-word;
  word-break:break-word;
}

@media (max-width:760px){
  .policy-hint{max-width:none;}
}
@media (max-width:430px){
  .policy-hint{
    font-size:var(--fs-xs,12px);
    line-height:1.55;
    text-wrap:balance;
    letter-spacing:0;
  }
}


/* ============================================================================
   v6.1（2026-10-03）：帳戶制度（14 日試用／只讀／訂閱）＋升級漏斗 class 契約
   ----------------------------------------------------------------------------
   依據 SPEC_ACCOUNTS_TRIAL_2026-10-03.md（Phase 2「trial 啟動卡」／
   Phase 3「兩步註冊」／Phase 4「升級漏斗」）。功能由其他 agent 實作，
   本段只提供佢哋要用嘅 class 樣式。
   ⚠️ 命名空間：本段嘅 T1–T7 係「帳戶制度」編號，同 v6.0 段嘅 T1–T9
      （Comment 3–10：.hw-card／.mf-pager／.q-flag／.team-hero／.team-logo-sm／
      .member-masked／.master-card／.own-preg／.policy-hint）係兩批完全獨立嘅
      UI —— class 名零重疊，互不影響。本段每個 section 標題都帶「帳戶」字樣，
      以免同 v6.0 混淆。
   ⚠️ 全部追加喺檔案末端（原本 2930 行）。上面既有 rule 一個字都冇改、冇
      reformat；新值一律靠「後寫者生效」或者本段**新建**嘅 media query 生效，
      冇刪除／改寫任何既有宣告。
   ⚠️ 純 CSS：冇引入 framework／library、冇 @import、冇 !important。
   ⚠️ 冇重新定義 body 嘅 font-weight／line-height（v5.9 定案 500／1.58）。
   ⚠️ design token 一律 var(--*) 並寫 fallback，而且只使用 :root 實有嘅 token
      （--brand／--brand-dark／--brand-soft／--mint／--mint-dark／--mint-soft／
      --coral／--coral-dark／--coral-soft／--gold／--gold-dark／--gold-soft／
      --card／--card-border／--card-radius／--card-shadow／--surface／--line／
      --ink／--ink-soft／--slate-150／--radius-pill／--gap／--gap-sm／--fs-*）。
      冇對應 token 嘅色（淺灰紫、mint 淺邊）跟 .tag-gold 既有做法寫死 hex，
      並喺註解標明。
   ⚠️ 字級一律用既有 scale（--fs-2xs 10.5／--fs-xs 12／--fs-sm 13.5／
      --fs-base 15／--fs-md 16.5／--fs-lg 18／--fs-xl 22／--fs-2xl 28／
      --fs-3xl 38）＋ fallback，唔另創新字級。
   ⚠️ 熱區 ≥44×44：本段所有掣／可撳元素都用 min-height:44px 撐大（.reg-pick
      用 76px），唔用 transform、唔用負 margin。輸入框亦設 min-height:44px。
   ⚠️ 三尺寸：desktop（預設）／tablet（≤1024、≤760）／mobile（≤430），
      另按需要加 ≤600（跟現有 .hw-*／.exam-pager 手機斷點習慣）。
   ============================================================================ */


/* ===========================================================================
   帳戶 T1：啟動 14 日免費試用卡
   class 契約：.trial-card／.trial-count／.trial-err
   附帶（可選，JS 用唔用都得；全部係新 class，唔會撞任何舊樣式）：
     .trial-head／.trial-title／.trial-sub／.trial-form／.trial-row／
     .trial-code／.trial-go／.trial-send
   ---------------------------------------------------------------------------
   卡底 = 白 → var(--mint-soft) 薄荷綠漸變，表示「免費」；卡面其餘跟全站卡片
   （同 .card 同一套 --card-* 代幣）。掣本身亦係 mint 漸變
   （同現有 .btn-mint 同色系），「傳送驗證碼」／「確認」共用一個外觀。
   ≤760px：.trial-row 換行、掣變全闊；≤430px：內距同字級各收一級。
   =========================================================================== */

.trial-card{
  position:relative;
  box-sizing:border-box;
  width:100%;
  min-width:0;
  padding:20px 20px 18px;
  margin-bottom:var(--gap,14px);
  /* mint 淺邊：:root 冇 mint 邊框 token，跟 #app-nav 既有 mint 邊用色 */
  border:1px solid #B6E7D2;
  border-radius:var(--card-radius,16px);
  box-shadow:var(--card-shadow,0 1px 2px rgba(15,23,42,.04), 0 6px 16px rgba(15,23,42,.05));
  background:linear-gradient(180deg,#FFFFFF 0%,#FFFFFF 42%,var(--mint-soft,#E7F8F1) 100%);
  color:var(--ink,#0F172A);
}
.trial-card > *{min-width:0;}

.trial-head{display:block;min-width:0;}
.trial-title{
  display:block;
  margin:0;
  font-size:var(--fs-lg,18px);
  font-weight:900;
  line-height:1.3;
  color:var(--ink,#0F172A);
  overflow-wrap:break-word;
  word-break:break-word;
}
.trial-sub{
  display:block;
  margin:4px 0 0;
  font-size:var(--fs-sm,13.5px);
  font-weight:700;
  line-height:1.55;
  color:var(--ink-soft,#475569);
  overflow-wrap:break-word;
  word-break:break-word;
}

.trial-form{
  display:flex;
  flex-direction:column;
  gap:12px;
  min-width:0;
  margin-top:14px;
}
.trial-row{
  display:flex;
  align-items:center;
  gap:10px;
  min-width:0;
}
.trial-row > .input,
.trial-row > input{flex:1 1 auto;min-width:0;}
.trial-row > .trial-go,
.trial-row > .trial-send,
.trial-row > .btn{flex:none;}

/* 手機號碼／驗證碼輸入：白底、mint focus ring、熱區 ≥44（16.5px 避免 iOS 自動放大） */
.trial-card input[type=text],
.trial-card input[type=tel],
.trial-card input[type=number],
.trial-card input[type=email],
.trial-card .input{
  box-sizing:border-box;
  width:100%;
  min-width:0;
  min-height:44px;
  padding:11px 15px;
  font-family:inherit;
  font-size:var(--fs-md,16.5px);
  font-weight:700;
  color:var(--ink,#0F172A);
  background:var(--card,#fff);
  border:1.5px solid var(--line,#E2E8F0);
  border-radius:14px;
  outline:none;
  transition:border-color .15s ease, box-shadow .15s ease;
}
.trial-card input:focus,
.trial-card .input:focus{
  border-color:var(--mint,#10B981);
  box-shadow:0 0 0 3px rgba(16,185,129,.16);
}
.trial-card .trial-code{
  text-align:center;
  letter-spacing:.30em;
  font-variant-numeric:tabular-nums;
}

/* 主要動作掣（傳送驗證碼／確認）：mint 漸變 + 立體下壓，跟 .btn 同一個互動語言 */
.trial-go,
.trial-send,
.trial-card .btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:6px;
  min-width:44px;
  min-height:44px;
  padding:11px 22px;
  font-family:inherit;
  font-size:var(--fs-base,15px);
  font-weight:800;
  line-height:1.2;
  color:#fff;
  background:linear-gradient(180deg,var(--mint,#10B981) 0%,var(--mint-dark,#0B8F63) 100%);
  border:none;
  border-radius:var(--radius-pill,999px);
  box-shadow:0 3px 0 0 var(--mint-dark,#0B8F63);
  cursor:pointer;
  text-decoration:none;
  white-space:nowrap;
  transition:transform .06s ease, box-shadow .06s ease, background .15s ease;
}
.trial-go:hover,
.trial-send:hover,
.trial-card .btn:hover{
  background:var(--mint-dark,#0B8F63);
  text-decoration:none;
}
.trial-go:active,
.trial-send:active,
.trial-card .btn:active{
  transform:translateY(3px);
  box-shadow:0 0 0 0 var(--mint-dark,#0B8F63);
}
.trial-go:focus-visible,
.trial-send:focus-visible,
.trial-card .btn:focus-visible{
  outline:2px solid var(--mint-dark,#0B8F63);
  outline-offset:2px;
}
/* 次要動作（例如「傳送驗證碼」做次級、只留 mint 邊）：JS 加 .btn-soft 就出呢個樣 */
.trial-card .btn-soft{
  background:var(--card,#fff);
  color:var(--mint-dark,#0B8F63);
  border:1.5px solid #B6E7D2;
  box-shadow:0 3px 0 0 #D8F0E5;
}
.trial-card .btn-soft:hover{background:var(--mint-soft,#E7F8F1);color:var(--mint-dark,#0B8F63);}
.trial-card .btn-soft:active{box-shadow:0 0 0 0 #D8F0E5;}
.trial-go:disabled,
.trial-send:disabled,
.trial-card .btn:disabled,
.trial-card .btn[disabled]{
  background:var(--slate-150,#E9EEF5);
  color:#94A3B8;
  box-shadow:none;
  cursor:not-allowed;
  transform:none;
}

/* 倒數細字：「59 秒後可重傳」；等寬數字避免每秒跳位。空嘅時候唔留白。 */
.trial-count{
  display:inline-block;
  margin-top:8px;
  min-height:18px;
  font-size:var(--fs-xs,12px);
  font-weight:800;
  line-height:1.5;
  color:var(--ink-soft,#475569);
  font-variant-numeric:tabular-nums;
  overflow-wrap:break-word;
  word-break:break-word;
}
.trial-count.ready{color:var(--mint-dark,#0B8F63);}
.trial-count:empty{display:none;}

/* 錯誤訊息：coral 細字；空嘅時候完全唔佔位（唔會頂高張卡） */
.trial-err{
  display:block;
  margin-top:8px;
  font-size:var(--fs-xs,12px);
  font-weight:800;
  line-height:1.5;
  color:var(--coral-dark,#C42D48);
  overflow-wrap:break-word;
  word-break:break-word;
}
.trial-err:empty{display:none;}

/* --- 帳戶 T1 三尺寸 --- */
@media (max-width:760px){
  .trial-card{padding:18px 16px 16px;}
  /* 窄螢幕：一行容唔落 → 輸入框獨佔一行、掣獨佔一行而且全闊 */
  .trial-row{flex-wrap:wrap;row-gap:10px;}
  .trial-row > .input,
  .trial-row > input{flex:1 1 100%;}
  .trial-row > .trial-go,
  .trial-row > .trial-send,
  .trial-row > .btn{flex:1 1 100%;width:100%;}
  .trial-card > .btn,
  .trial-form > .btn,
  .trial-card > .trial-go,
  .trial-form > .trial-go{width:100%;}
}
@media (max-width:430px){
  .trial-card{padding:16px 13px 14px;margin-bottom:var(--gap-sm,10px);}
  .trial-title{font-size:var(--fs-md,16.5px);}
  .trial-sub{font-size:var(--fs-xs,12px);}
  .trial-form{gap:10px;margin-top:12px;}
  .trial-card input[type=text],
  .trial-card input[type=tel],
  .trial-card input[type=number],
  .trial-card input[type=email],
  .trial-card .input{padding:10px 13px;}
  .trial-go,
  .trial-send,
  .trial-card .btn{padding:11px 18px;font-size:var(--fs-sm,13.5px);}
}


/* ===========================================================================
   帳戶 T2：兩步註冊（步驟指示器 ＋ 大粒身份選擇卡）
   class 契約：.reg-steps／.reg-step／.reg-step-num／.reg-pick
   附帶（可選）：.reg-pick-icon／.reg-pick-text／.reg-pick-name／.reg-pick-sub
   ---------------------------------------------------------------------------
   ⚠️ .reg-step 係「每一步嘅容器」，刻意**唔設 display**：JS 用 hidden 屬性
      （或 display:none）切換步驟時唔會被本段覆蓋，hidden 一定生效。
   ⚠️ 步驟指示器唔會自動加「—」分隔線（避免同 JS 自己嘅分隔符重複），
      只靠 gap 分隔；當前步高亮用 .on／.active／[aria-current="step"] 任一。
   ⚠️ .reg-pick 比現有 .choice（padding 14px 16px／16px 字）明顯大：76px 高、
      18px 圓角、26px icon；可換行，唔會將細字撐爆卡。
   =========================================================================== */

.reg-steps{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:8px 10px;
  min-width:0;
  margin:0 0 14px;
  font-size:var(--fs-sm,13.5px);
  font-weight:800;
  line-height:1.4;
  color:#94A3B8;                      /* 未到嘅步驟：低調灰 */
}
.reg-steps > *{min-width:0;}
/* 當前步：brand 色高亮（文字 + 徽章） */
.reg-steps .on,
.reg-steps .active,
.reg-steps [aria-current="step"]{color:var(--brand,#2A5CE8);}
/* 已完成嘅步驟：mint，表示「過咗」而唔係「未到」 */
.reg-steps .done{color:var(--mint-dark,#0B8F63);}

.reg-step{
  padding:12px 0 14px;
  min-width:0;
}
.reg-step:first-child{padding-top:0;}
.reg-step + .reg-step{border-top:1px dashed var(--line,#E2E8F0);}

/* 圓形數字徽章：22–24px、brand 底白字 */
.reg-step-num{
  flex:none;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:24px;
  height:24px;
  border-radius:50%;
  background:var(--brand,#2A5CE8);
  color:#fff;
  font-size:var(--fs-xs,12px);
  font-weight:900;
  line-height:1;
  font-variant-numeric:tabular-nums;
  box-sizing:border-box;
  user-select:none;
}
/* 喺指示器入面：未到嘅步驟徽章變灰、現正嗰個保持 brand 底、已完成轉 mint */
.reg-steps .reg-step-num{background:#CBD5E1;color:#fff;}
.reg-steps .on .reg-step-num,
.reg-steps .active .reg-step-num,
.reg-steps [aria-current="step"] .reg-step-num,
.reg-steps .reg-step-num.on{background:var(--brand,#2A5CE8);color:#fff;}
.reg-steps .done .reg-step-num,
.reg-steps .reg-step-num.done{background:var(--mint,#10B981);color:#fff;}

/* 大粒身份選擇卡（「我自己用（學生）」／「我係家長」）：icon ＋ 主標題 ＋ 一行細字 */
.reg-pick{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:4px 12px;
  box-sizing:border-box;
  width:100%;
  min-width:0;
  min-height:76px;                    /* 遠大於 44 熱區，手指好撳 */
  padding:16px 18px;
  text-align:left;
  font-family:inherit;
  color:var(--ink,#0F172A);
  background:var(--card,#fff);
  border:2px solid var(--line,#E2E8F0);
  border-radius:18px;
  box-shadow:0 3px 0 0 var(--line,#E2E8F0);
  cursor:pointer;
  transition:border-color .15s ease, background .15s ease,
    transform .06s ease, box-shadow .06s ease;
}
.reg-pick + .reg-pick{margin-top:var(--gap-sm,10px);}
.reg-pick:hover{border-color:#93B4FF;background:#F7FAFF;}
.reg-pick:active{transform:translateY(3px);box-shadow:0 0 0 0 var(--line,#E2E8F0);}
.reg-pick:focus-visible{outline:2px solid var(--brand,#2A5CE8);outline-offset:2px;}
/* 已選中：brand 邊 ＋ 淺藍底（同 .choice.sel／.pick-card.on 同一語言） */
.reg-pick.on,
.reg-pick.sel,
.reg-pick[aria-checked="true"]{
  border-color:var(--brand,#2A5CE8);
  background:var(--brand-soft,#EEF3FE);
  box-shadow:0 3px 0 0 var(--brand,#2A5CE8);
}

.reg-pick-icon,
.reg-pick .pc-icon{
  flex:none;
  font-size:26px;
  line-height:1.1;
  width:34px;
  text-align:center;
}
.reg-pick-text,
.reg-pick > div,
.reg-pick > span:not(.reg-pick-icon){
  flex:1 1 160px;
  min-width:0;
}
.reg-pick-name,
.reg-pick .pc-name{
  display:block;
  font-size:var(--fs-md,16.5px);
  font-weight:900;
  line-height:1.3;
  color:var(--ink,#0F172A);
  overflow-wrap:break-word;
  word-break:break-word;
}
.reg-pick.on .reg-pick-name,
.reg-pick.sel .reg-pick-name,
.reg-pick.on .pc-name,
.reg-pick.sel .pc-name{color:var(--brand,#2A5CE8);}
.reg-pick-sub,
.reg-pick .pc-sub{
  display:block;
  margin-top:2px;
  font-size:var(--fs-xs,12px);
  font-weight:700;
  line-height:1.5;
  color:var(--ink-soft,#475569);
  overflow-wrap:break-word;
  word-break:break-word;
}

/* --- 帳戶 T2 三尺寸 --- */
@media (max-width:760px){
  .reg-steps{margin-bottom:12px;}
  .reg-pick{padding:14px 16px;}
}
@media (max-width:430px){
  .reg-steps{gap:6px 8px;font-size:var(--fs-xs,12px);}
  .reg-step{padding:10px 0 12px;}
  .reg-step-num{width:22px;height:22px;font-size:var(--fs-2xs,10.5px);}
  .reg-pick{
    min-height:68px;
    padding:13px 14px;
    gap:4px 10px;
    border-radius:16px;
  }
  .reg-pick-icon,
  .reg-pick .pc-icon{font-size:24px;width:30px;}
  .reg-pick-name,
  .reg-pick .pc-name{font-size:var(--fs-base,15px);}
}


/* ===========================================================================
   帳戶 T3：帳戶狀態卡
   class 契約：.acct-card／.acct-badge／.acct-days／.acct-bar
   附帶（可選）：.acct-head／.acct-title／.acct-meta／.acct-go
   ---------------------------------------------------------------------------
   白卡（跟全站 .card 同一套 --card-* 代幣）＋ 左邊 6px 粗色條分辨三種狀態：
     · trial 中      → mint   （.trial／.is-trial／[data-state="trial"]）
     · 只讀（過期）  → coral  （.expired／.readonly／[data-state="expired"]／
                               [data-state="readonly"]）
     · 已訂閱        → gold   （.sub／.subscribed／[data-state="sub"]／
                               [data-state="subscribed"]）
   ⚠️ 色條同進度條填充用同一個自訂屬性 --acct-accent（純 CSS 自訂屬性，
      唔係任何 library）：狀態 class 一改，左邊色條同進度條一齊變色，唔會唔一致。
      冇狀態 class 時 fallback 去品牌藍。
   ⚠️ 大數字同進度條一律唔跟狀態變色（維持 --ink／--accent 以外嘅中性色），
      係為咗 28px 粗體字嘅對比度：gold-dark 落白底只有約 2.7:1，唔夠。
   =========================================================================== */

.acct-card{
  --acct-accent:linear-gradient(180deg,var(--brand,#2A5CE8) 0%,var(--brand-dark,#1E46B8) 100%);
  position:relative;
  box-sizing:border-box;
  width:100%;
  min-width:0;
  padding:16px 18px 16px 22px;
  margin-bottom:var(--gap,14px);
  background:var(--card,#fff);
  border:1px solid var(--card-border,rgba(226,232,240,.9));
  border-radius:var(--card-radius,16px);
  box-shadow:var(--card-shadow,0 1px 2px rgba(15,23,42,.04), 0 6px 16px rgba(15,23,42,.05));
  color:var(--ink,#0F172A);
  overflow:hidden;
}
.acct-card > *{min-width:0;}
.acct-card::before{
  content:"";
  position:absolute;
  left:0;
  top:0;
  bottom:0;
  width:6px;                          /* 左邊粗色條 */
  background:var(--acct-accent);
  pointer-events:none;
}
.acct-card.trial,
.acct-card.is-trial,
.acct-card[data-state="trial"]{
  --acct-accent:linear-gradient(180deg,var(--mint,#10B981) 0%,var(--mint-dark,#0B8F63) 100%);
}
.acct-card.expired,
.acct-card.readonly,
.acct-card.is-expired,
.acct-card.is-readonly,
.acct-card[data-state="expired"],
.acct-card[data-state="readonly"]{
  --acct-accent:linear-gradient(180deg,var(--coral,#F43F5E) 0%,var(--coral-dark,#C42D48) 100%);
}
.acct-card.sub,
.acct-card.subscribed,
.acct-card.is-sub,
.acct-card.is-subscribed,
.acct-card[data-state="sub"],
.acct-card[data-state="subscribed"]{
  --acct-accent:linear-gradient(180deg,var(--gold,#FFB800) 0%,var(--gold-dark,#C98F00) 100%);
}

.acct-head{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:8px;
  min-width:0;
}
.acct-title{
  min-width:0;
  font-size:var(--fs-md,16.5px);
  font-weight:900;
  line-height:1.3;
  color:var(--ink,#0F172A);
  overflow-wrap:break-word;
  word-break:break-word;
}
.acct-meta{
  margin-top:4px;
  font-size:var(--fs-xs,12px);
  font-weight:700;
  line-height:1.55;
  color:var(--ink-soft,#475569);
  overflow-wrap:break-word;
  word-break:break-word;
}

/* 小 pill：「體驗帳號」／「已訂閱」／「只讀」。JS 唔指定變體＝中性灰。 */
.acct-badge{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:4px;
  padding:3px 10px;
  border-radius:var(--radius-pill,999px);
  font-size:11px;
  font-weight:800;
  line-height:1.35;
  white-space:nowrap;
  background:var(--slate-150,#E9EEF5);
  color:var(--ink-soft,#475569);
}
.acct-badge.trial{background:var(--mint-soft,#E7F8F1);color:var(--mint-dark,#0B8F63);}
.acct-badge.sub,
.acct-badge.subscribed{background:var(--gold-soft,#FFF6E0);color:#8A5A00;}
.acct-badge.expired,
.acct-badge.readonly{background:var(--coral-soft,#FEECEF);color:var(--coral-dark,#C42D48);}

/* 大數字倒數（「仲有 12 日」）：28px／900／等寬數字，唔會因為數字變動而跳位 */
.acct-days{
  display:block;
  margin:6px 0 0;
  font-size:var(--fs-2xl,28px);
  font-weight:900;
  line-height:1.15;
  letter-spacing:-.4px;
  color:var(--ink,#0F172A);
  font-variant-numeric:tabular-nums;
  overflow-wrap:break-word;
  word-break:break-word;
}

/* 進度條（trial 剩餘百分比）：8px 高、全圓角；填充色跟 --acct-accent */
.acct-bar{
  position:relative;
  display:block;
  box-sizing:border-box;
  width:100%;
  height:8px;
  margin-top:10px;
  background:var(--surface,#F1F5F9);
  border-radius:var(--radius-pill,999px);
  overflow:hidden;
}
.acct-bar > i,
.acct-bar > b,
.acct-bar > .acct-bar-fill{
  display:block;
  height:100%;
  width:0;
  border-radius:var(--radius-pill,999px);
  background:var(--acct-accent,var(--brand,#2A5CE8));
  transition:width .4s cubic-bezier(.2,.8,.2,1);
}

/* 狀態卡入面嘅行動掣（立即升級／升級）：≥44 熱區；窄螢幕全闊 */
.acct-go,
.acct-card .btn{
  min-height:44px;
  margin-top:12px;
  white-space:nowrap;
}

@media (max-width:760px){
  .acct-card{padding:14px 15px 14px 20px;}
}
@media (max-width:600px){
  .acct-go,
  .acct-card .btn{width:100%;}
}
@media (max-width:430px){
  .acct-card{padding:13px 13px 13px 18px;margin-bottom:var(--gap-sm,10px);}
  .acct-title{font-size:var(--fs-base,15px);}
  .acct-days{font-size:var(--fs-xl,22px);}   /* mobile 收一級（22px） */
  .acct-bar{height:8px;margin-top:8px;}
  .acct-go,
  .acct-card .btn{font-size:var(--fs-sm,13.5px);}
}


/* ===========================================================================
   帳戶 T4：只讀橫額（試用完結）
   class 契約：.readonly-banner
   附帶（可選）：.readonly-banner-icon／.readonly-banner-text／.readonly-banner-up
   ---------------------------------------------------------------------------
   建議 DOM（JS 側；有 icon＋文字包裝就先夠穩）：
     <div class="readonly-banner" role="status">
       <span class="readonly-banner-icon" aria-hidden="true">🔒</span>
       <p class="readonly-banner-text">…一句提示…</p>
       <a class="btn readonly-banner-up" href="#/upgrade">升級</a>
     </div>
   ⚠️ 冇包裝層都唔會爆：icon／文字／掣係 flex 子項，文字 flex-basis 200px 可以
      壓縮同換行，掣 flex:none 唔會被擠扁（≥44 熱區）。
   ⚠️ 窄螢幕（≤600px）掣變全闊獨佔一行＝「文字一行、掣一行」，唔會同文字爭位。
   =========================================================================== */

.readonly-banner{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:8px 12px;
  box-sizing:border-box;
  width:100%;
  min-width:0;
  padding:12px 14px;
  margin:0 0 var(--gap,14px);
  background:var(--coral-soft,#FEECEF);
  border:1.5px solid #F7C6CE;         /* coral 淺邊：:root 冇 token，寫死 */
  border-radius:var(--card-radius,16px);
  color:var(--coral-dark,#C42D48);
  font-size:var(--fs-sm,13.5px);
  font-weight:800;
  line-height:1.5;
}
.readonly-banner > *{min-width:0;}
.readonly-banner-icon,
.readonly-banner > svg:first-child{
  flex:none;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:28px;
  height:28px;
  border-radius:50%;
  background:rgba(244,63,94,.14);
  color:var(--coral-dark,#C42D48);
  font-size:var(--fs-base,15px);
  line-height:1;
  text-align:center;
}
.readonly-banner-text,
.readonly-banner p,
.readonly-banner > span:not(.readonly-banner-icon){
  flex:1 1 200px;
  min-width:0;
  margin:0;
  color:var(--coral-dark,#C42D48);
  overflow-wrap:break-word;
  word-break:break-word;
}
.readonly-banner-up,
.readonly-banner .btn{
  flex:none;
  margin-left:auto;
  min-width:44px;
  min-height:44px;                    /* 熱區 ≥44×44 */
  white-space:nowrap;
}

@media (max-width:760px){
  .readonly-banner{padding:11px 12px;gap:8px 10px;}
}
@media (max-width:600px){
  /* 文字一行、掣一行（掣全闊，手指好撳） */
  .readonly-banner-up,
  .readonly-banner .btn{
    flex:1 1 100%;
    width:100%;
    margin-left:0;
  }
}
@media (max-width:430px){
  .readonly-banner{
    padding:11px 12px;
    font-size:var(--fs-xs,12px);
    border-radius:14px;
  }
  .readonly-banner-icon,
  .readonly-banner > svg:first-child{width:26px;height:26px;font-size:var(--fs-sm,13.5px);}
}


/* ===========================================================================
   帳戶 T5：升級頁 plan 卡
   class 契約：.plan-grid／.plan-card／.plan-price／.plan-save
   附帶（可選）：.plan-name／.plan-period／.plan-feat／.plan-go
   ---------------------------------------------------------------------------
   桌面 3 欄 → ≤760px 1 欄；可選中（.on／.sel／[aria-checked="true"] = brand 邊
   ＋ 淺藍底 ＋ brand 立體底邊）；「即將推出」用 .plan-card.soon（灰、opacity .6、
      冇 hover／press 反應、cursor:default，一眼睇得出唔撳得）。
   ⚠️ .plan-price 用 var(--fs-2xl) = 28px（既有字級 scale 值，喺契約 28–34px
      之內）；進度／價格一律 font-variant-numeric:tabular-nums，換數字唔跳位。
   =========================================================================== */

.plan-grid{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:14px;
  min-width:0;
  margin:0 0 var(--gap,14px);
}
.plan-grid > *{min-width:0;}

.plan-card{
  position:relative;
  display:flex;
  flex-direction:column;
  box-sizing:border-box;
  min-width:0;
  padding:18px 18px 16px;
  text-align:left;
  font-family:inherit;
  color:var(--ink,#0F172A);
  background:var(--card,#fff);
  border:2px solid var(--line,#E2E8F0);
  border-radius:var(--card-radius,16px);
  box-shadow:0 3px 0 0 var(--line,#E2E8F0);
  cursor:pointer;
  transition:border-color .15s ease, background .15s ease,
    transform .06s ease, box-shadow .06s ease;
}
.plan-card:hover{border-color:#93B4FF;background:#F7FAFF;}
.plan-card:active{transform:translateY(3px);box-shadow:0 0 0 0 var(--line,#E2E8F0);}
.plan-card:focus-visible{outline:2px solid var(--brand,#2A5CE8);outline-offset:2px;}
/* 已選中 */
.plan-card.on,
.plan-card.sel,
.plan-card[aria-checked="true"]{
  border-color:var(--brand,#2A5CE8);
  background:var(--brand-soft,#EEF3FE);
  box-shadow:0 3px 0 0 var(--brand,#2A5CE8);
}
.plan-card.on:hover,
.plan-card.sel:hover{border-color:var(--brand,#2A5CE8);background:var(--brand-soft,#EEF3FE);}

.plan-card .plan-name{
  font-size:var(--fs-md,16.5px);
  font-weight:900;
  line-height:1.3;
  color:var(--ink,#0F172A);
}
.plan-card .plan-period{
  display:block;
  margin-top:2px;
  font-size:var(--fs-xs,12px);
  font-weight:700;
  line-height:1.5;
  color:var(--ink-soft,#475569);
}
.plan-price{
  display:block;
  margin:6px 0 0;
  font-size:var(--fs-2xl,28px);
  font-weight:900;
  line-height:1.1;
  letter-spacing:-.6px;
  color:var(--ink,#0F172A);
  font-variant-numeric:tabular-nums;
  overflow-wrap:break-word;
  word-break:break-word;
}
.plan-card.on .plan-price{color:var(--brand,#2A5CE8);}

/* 金色小 pill（「慳 17%」）：同 .tag-gold 同一組色 */
.plan-save{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:4px;
  padding:2px 8px;
  border-radius:var(--radius-pill,999px);
  font-size:11px;
  font-weight:800;
  line-height:1.5;
  white-space:nowrap;
  background:var(--gold-soft,#FFF6E0);
  color:#8A5A00;
}

/* plan 卡入面嘅功能清單（如果 JS 用 ul/li） */
.plan-card ul,
.plan-card ol{
  margin:8px 0 0;
  padding-left:18px;
}
.plan-card li{
  font-size:var(--fs-xs,12px);
  font-weight:700;
  line-height:1.6;
  color:var(--ink-soft,#475569);
  overflow-wrap:break-word;
  word-break:break-word;
}

/* 卡底行動掣：靠 margin-top:auto 令同一行嘅卡掣底對齊；≥44 熱區 */
.plan-go,
.plan-card .btn{
  margin-top:auto;
  min-height:44px;
  width:100%;
  white-space:nowrap;
}

/* 「即將推出」：灰、半透明、冇任何撳得嘅反饋 */
.plan-card.soon{
  background:var(--surface,#F1F5F9);
  border-color:var(--line,#E2E8F0);
  box-shadow:none;
  opacity:.6;
  cursor:default;
  filter:grayscale(.35);
}
.plan-card.soon:hover{
  background:var(--surface,#F1F5F9);
  border-color:var(--line,#E2E8F0);
  transform:none;
  box-shadow:none;
}
.plan-card.soon:active{transform:none;box-shadow:none;}
.plan-card.soon .plan-price,
.plan-card.soon .plan-name{color:var(--ink-soft,#475569);}
.plan-card.soon .plan-save{background:var(--slate-150,#E9EEF5);color:var(--ink-soft,#475569);}
.plan-card.soon .btn,
.plan-card.soon .plan-go{
  background:var(--slate-150,#E9EEF5);
  color:#94A3B8;
  box-shadow:none;
  cursor:not-allowed;
  transform:none;
}

@media (max-width:1024px){
  .plan-grid{gap:12px;}
  .plan-card{padding:16px 15px 14px;}
}
@media (max-width:760px){
  .plan-grid{grid-template-columns:1fr;gap:12px;}
}
@media (max-width:430px){
  .plan-card{padding:15px 14px 13px;border-radius:14px;}
  .plan-card .plan-name,
  .plan-card .plan-period{margin-top:0;}
  .plan-go,
  .plan-card .btn{font-size:var(--fs-sm,13.5px);}
}


/* ===========================================================================
   帳戶 T6：升級等待名單（waitlist）
   class 契約：.waitlist-box／.waitlist-ok
   附帶（可選）：.waitlist-form／.waitlist-row／.waitlist-go／.waitlist-err
   ---------------------------------------------------------------------------
   電郵輸入 ＋「推出時通知我」掣（≥44 熱區）＋ 成功訊息（.waitlist-ok，mint）。
   ≤760px：輸入框同掣各佔一行、掣全闊。
   =========================================================================== */

.waitlist-box{
  box-sizing:border-box;
  width:100%;
  min-width:0;
  margin-top:12px;
  padding:14px 16px;
  background:var(--surface,#F1F5F9);
  border:1px solid var(--line,#E2E8F0);
  border-radius:16px;
}
.waitlist-box > *{min-width:0;}
.waitlist-form,
.waitlist-row{
  display:flex;
  align-items:center;
  gap:10px;
  min-width:0;
}
.waitlist-box input[type=email],
.waitlist-box input[type=text],
.waitlist-box .input{
  box-sizing:border-box;
  flex:1 1 auto;
  min-width:0;
  min-height:44px;
  padding:11px 15px;
  font-family:inherit;
  font-size:var(--fs-md,16.5px);
  font-weight:700;
  color:var(--ink,#0F172A);
  background:var(--card,#fff);
  border:1.5px solid var(--line,#E2E8F0);
  border-radius:14px;
  outline:none;
  transition:border-color .15s ease, box-shadow .15s ease;
}
.waitlist-box input:focus,
.waitlist-box .input:focus{
  border-color:var(--brand,#2A5CE8);
  box-shadow:0 0 0 3px rgba(42,92,232,.14);
}
.waitlist-go,
.waitlist-box .btn{
  flex:none;
  min-width:44px;
  min-height:44px;
  white-space:nowrap;
}

.waitlist-ok{
  display:block;
  margin-top:10px;
  padding:8px 12px;
  border-radius:12px;
  background:var(--mint-soft,#E7F8F1);
  color:var(--mint-dark,#0B8F63);
  font-size:var(--fs-xs,12px);
  font-weight:800;
  line-height:1.5;
  overflow-wrap:break-word;
  word-break:break-word;
}
.waitlist-ok:empty{display:none;}
.waitlist-err{
  display:block;
  margin-top:8px;
  font-size:var(--fs-xs,12px);
  font-weight:800;
  line-height:1.5;
  color:var(--coral-dark,#C42D48);
  overflow-wrap:break-word;
  word-break:break-word;
}
.waitlist-err:empty{display:none;}

@media (max-width:760px){
  .waitlist-box{padding:13px 14px;}
  .waitlist-form,
  .waitlist-row{flex-wrap:wrap;row-gap:10px;}
  .waitlist-box input[type=email],
  .waitlist-box input[type=text],
  .waitlist-box .input{flex:1 1 100%;}
  .waitlist-go,
  .waitlist-box .btn{flex:1 1 100%;width:100%;}
}
@media (max-width:430px){
  .waitlist-box{padding:12px 12px;border-radius:14px;}
  .waitlist-box input[type=email],
  .waitlist-box input[type=text],
  .waitlist-box .input{padding:10px 13px;}
  .waitlist-go,
  .waitlist-box .btn{font-size:var(--fs-sm,13.5px);}
}


/* ===========================================================================
   帳戶 T7：全站「體驗帳號」徽章
   class 契約：.tag-trial
   ---------------------------------------------------------------------------
   用喺 header／排行榜／團隊成員名單。尺寸完全跟 .tag 最後生效值
   （11px／padding 2px 8px／border-radius 8px／font-weight 800／nowrap），
   但色系係**淺灰紫**：#EFECFA 底 ＋ #5B4E96 字（對比約 5.9:1，過 AA），
   刻意避開品牌藍／薄荷／金色 —— 一眼分得出「體驗帳號」同其他 tag 唔同類。
   ⚠️ :root 冇淺灰紫 token，跟 .tag-gold（color:#8A5A00）既有做法寫死 hex。
   ⚠️ 單獨用（class="tag-trial"）或者同 .tag 一齊用（class="tag tag-trial"）
      都一樣樣：本段喺 .tag 之後，所以 background／color 一定贏。
   =========================================================================== */

.tag-trial{
  display:inline-block;
  font-size:11px;
  font-weight:800;
  line-height:1.5;
  padding:2px 8px;
  border-radius:8px;
  white-space:nowrap;
  vertical-align:middle;
  background:#EFECFA;
  color:#5B4E96;
}

@media (max-width:430px){
  /* 跟 .tag 自己嘅窄螢幕值一致（唔再加細，維持可讀） */
  .tag-trial{font-size:11px;padding:2px 8px;}
}


/* ===========================================================================
   v6.1 補遺（同一次 append 嘅收尾；真瀏覽器量度之後嘅兩項微調）
   ---------------------------------------------------------------------------
   ① .reg-pick／.plan-card 如果寫成 <button>（契約話「可撳」，好大機會係），
      Chrome UA 會俾佢 font-size:13.333px／font-weight:400 —— 實測確認
      （320／393／768／1280 四個闊度都係 13.3333px／400）。兩個 class 本身
      只設 icon／name／sub 嘅字級，所以「直接放喺容器嘅文字」會變咗細字。
      下面明確聲明容器字級 15px（.reg-pick 用 800，同 .choice 一致；
      .plan-card 用 700，同全站 body 一致）—— 呢兩條 rule 喺本段之前從未
      設過 font-size／font-weight，所以唔會覆蓋本段任何舊宣告。
   ② 註冊 Step 1 用既有 .field／.input：實測高度 42px，差 2px 未達 44 熱區
      （量度：input.text.input=xxx x 42.0，四個闊度都一樣）。喺 .reg-step
      範圍內補 min-height:44px（只影響新容器入面嘅表單；上面既有 .input／
      .field 嘅 rule 一個字都冇改、冇 reformat）。
   =========================================================================== */

.reg-pick,
.plan-card{
  font-size:var(--fs-base,15px);
}
.reg-pick{font-weight:800;}
.plan-card{font-weight:700;}

.reg-step .input,
.reg-step input[type=text],
.reg-step input[type=password],
.reg-step input[type=number],
.reg-step input[type=email],
.reg-step select{
  min-height:44px;
}

@media (max-width:430px){
  .reg-step .input,
  .reg-step input[type=text],
  .reg-step input[type=password],
  .reg-step input[type=number],
  .reg-step input[type=email],
  .reg-step select{
    min-height:44px;
  }
}

/* ============================================================================
   v5.14：造型 PNG 分層疊圖（avatar-art.js 由 SVG 改為 /assets/avatar/ 素材疊圖）
   容器（.header-avatar／.avatar-sm／.person-row-avatar／.profile-preview…）一律係
   display:flex ＋ 置中 ＋ border-radius:50% ＋ overflow:hidden，所以：
     ‧ .avatar-stack 一定要填滿容器（width/height 100%），大細由容器決定；
     ‧ 每層一律 object-fit:contain（唔可以用 cover，否則會裁走角色嘅頭或者腳）；
     ‧ 優先次序：.avatar-stack>.avatar-layer（0,2,0）高過 .header-avatar img（0,1,1），
       所以疊圖層一定贏上面寫死嘅 object-fit:cover。
   portrait 模式（細頭像用嘅頭肩特寫）嘅 transform 由 inline style 放喺 .avatar-stack 自己，
   唔可以放喺每層 img，否則逐層各自縮放會散開。
   ============================================================================ */
.avatar-stack{position:relative;display:inline-block;width:100%;height:100%;line-height:0;}
.avatar-stack>.avatar-layer{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;display:block;}
/* 單件素材（商店縮圖／預覽）唔係疊圖，唔可以 absolute ——
   冇 .avatar-stack 做定位祖先就會飛出容器 */
.avatar-part{width:100%;height:100%;object-fit:contain;display:block;}

/* 學庫幣圖示（ico_coin.png 取代錢幣 emoji）：跟住文字大細縮放、垂直置中 */
.coin-ico{width:1.05em;height:1.05em;vertical-align:-.16em;display:inline-block;}

/* ============================================================================
   v6.5：造型商店遊戲化（GAMING_UX_AVATAR_SHOP_2026-10-03 §3 Phase B）
   ⚠️ 全部喺檔尾 append，唔改上面任何既有規則；class 一律 shop- 開頭。
   ① 稀有度視覺語言：邊框色 ＋ 左上角角標（角標一定有文字＝色弱友善）、
      legend 微光（純 box-shadow，唔用圖）；
   ② 「今期焦點」大格；③ 開箱動畫（彈出＋金色光環，≤600ms）；
   ④ 新掣一律 min-height 44px（手機 tap target）＝ .shop-tap。
   色：free 灰 / starter 藍 / common 綠 / rare 紫 / epic 橙 / legend 金。
   ============================================================================ */

/* ---- ① 稀有度：商店格（.shop-item 同時用喺 grid 格仔同「今期焦點」大格） ---- */
.shop-item{
  position:relative;background:#fff;border:2px solid var(--line);border-radius:16px;
  padding:18px 10px 12px;                  /* 上邊留位畀左上角角標 */
  display:flex;flex-direction:column;align-items:center;gap:6px;text-align:center;
  font-family:inherit;color:inherit;min-width:0;width:100%;min-height:44px;
}
button.shop-item{cursor:pointer;}
.shop-item.shop-tier-free{border-color:#94A3B8;}
.shop-item.shop-tier-starter{border-color:#2A5CE8;}
.shop-item.shop-tier-common{border-color:#10B981;}
.shop-item.shop-tier-rare{border-color:#7C3AED;}
.shop-item.shop-tier-epic{border-color:#F97316;}
/* 傳說：金色邊框 ＋ 微光（純 CSS，唔用圖） */
.shop-item.shop-tier-legend{
  border-color:#FFB800;
  box-shadow:0 0 0 1px rgba(255,184,0,.55),0 0 20px rgba(255,184,0,.45);
}
/* 已擁有：內圈薄荷綠（同稀有度邊框並存，一眼分到「買咗未」） */
.shop-item.shop-owned{box-shadow:inset 0 0 0 2px var(--mint,#10B981);}
.shop-item.shop-owned.shop-tier-legend{
  box-shadow:0 0 0 1px rgba(255,184,0,.55),0 0 20px rgba(255,184,0,.45),
    inset 0 0 0 2px var(--mint,#10B981);
}

/* ---- 左上角角標：一定有文字（色弱友善） ---- */
.shop-tier-badge{
  position:absolute;top:-1px;left:-1px;z-index:2;pointer-events:none;
  font-size:11px;font-weight:900;line-height:1;letter-spacing:.5px;
  padding:5px 9px 6px;border-radius:15px 4px 15px 4px;color:#fff;background:#94A3B8;
}
.shop-tier-badge.shop-tier-free{background:#94A3B8;}
.shop-tier-badge.shop-tier-starter{background:#2A5CE8;}
.shop-tier-badge.shop-tier-common{background:#10B981;}
.shop-tier-badge.shop-tier-rare{background:#7C3AED;}
.shop-tier-badge.shop-tier-epic{background:#F97316;}
.shop-tier-badge.shop-tier-legend{background:#FFB800;color:#4A2E00;}
/* modal／開箱用嘅稀有度標籤（＝ .tag ＋ tier 色） */
.tag.shop-tier-tag{color:#fff;background:#94A3B8;}
.tag.shop-tier-tag.shop-tier-free{background:#94A3B8;}
.tag.shop-tier-tag.shop-tier-starter{background:#2A5CE8;}
.tag.shop-tier-tag.shop-tier-common{background:#10B981;}
.tag.shop-tier-tag.shop-tier-rare{background:#7C3AED;}
.tag.shop-tier-tag.shop-tier-epic{background:#F97316;}
.tag.shop-tier-tag.shop-tier-legend{background:#FFB800;color:#4A2E00;}

/* ---- ② 今期焦點 ---- */
.shop-featured{border:1px solid rgba(255,184,0,.5);background:linear-gradient(180deg,#FFFDF5,#fff);}
.shop-featured-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;}
.shop-featured-cell{padding-top:20px;}
.shop-featured-actions{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;width:100%;margin-top:4px;}
.shop-featured-actions>.btn{flex:1 1 auto;min-width:0;}

/* ---- ③ 開箱：彈出 ＋ 金色光環（≤600ms，純 CSS） ---- */
.shop-unbox{position:relative;}
.shop-unbox-stage{margin:0 auto;position:relative;z-index:1;}
.shop-unbox-ring{
  position:absolute;left:50%;top:96px;width:200px;height:200px;margin:0;
  transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;opacity:0;
  box-shadow:0 0 0 6px rgba(255,184,0,.35),0 0 44px 18px rgba(255,184,0,.5);
  animation:shop-unbox-ring 580ms ease-out both;
}
.shop-unbox-card{position:relative;animation:shop-unbox-pop 520ms cubic-bezier(.2,1.28,.42,1) both;}
@keyframes shop-unbox-pop{
  0%{transform:scale(.74);opacity:.25;}
  62%{transform:scale(1.04);opacity:1;}
  100%{transform:scale(1);opacity:1;}
}
@keyframes shop-unbox-ring{
  0%{opacity:0;transform:translate(-50%,-50%) scale(.55);}
  55%{opacity:1;transform:translate(-50%,-50%) scale(1.02);}
  100%{opacity:0;transform:translate(-50%,-50%) scale(1.18);}
}
/* 系統設定「減少動態效果」→ 唔播動畫（仍然有 modal，只係唔郁） */
@media (prefers-reduced-motion: reduce){
  .shop-unbox-card{animation:none;}
  .shop-unbox-ring{animation:none;opacity:.45;}
}

/* ---- ④ 提示行 ＋ 下一步 CTA ＋ 手機 tap target ---- */
.shop-hint{text-align:center;font-size:12.5px;line-height:1.6;color:var(--ink-soft,#475569);margin-top:8px;}
.shop-earn{width:100%;margin-top:8px;}
.shop-cta-row{display:flex;justify-content:center;margin-top:12px;}
.shop-cta-row>.btn{width:100%;}
/* 呢頁每個掣最少 44×44（iOS／Android tap target 指引） */
.shop-tap{min-height:44px;min-width:44px;}
.btn-brand{background:var(--brand);color:#fff;box-shadow:0 4px 0 0 var(--brand-dark);}
.btn-brand:hover{background:var(--primary-dark);}
.btn-brand:active{transform:translateY(4px);box-shadow:0 0 0 0 var(--brand-dark);}

/* ============================================================================
   v6.6：頭像光環（window.AVATAR_RING／UI.ringWrap）＋ 徽章小圖示 ＋ 放大看卡
   （UI.avatarModal）＋ 人物列／header 頭像加大。
   ⚠️ 全部喺檔尾 append，唔改上面任何既有規則。
   ============================================================================ */

/* ---- ① 光環：大圖（-lg）4px、列內細圖（-sm）2px；金＞銀＞銅 ---- */
.avatar-ring{display:inline-flex;flex:none;line-height:0;border-radius:50%;}
.avatar-ring-gold{box-shadow:0 0 0 4px #FFB800, 0 0 18px 4px rgba(255,184,0,.55);}
.avatar-ring-silver{box-shadow:0 0 0 4px #C0C0C0;}
.avatar-ring-bronze{box-shadow:0 0 0 4px #CD7F32;}
.avatar-ring-sm.avatar-ring-gold{box-shadow:0 0 0 2px #FFB800, 0 0 12px 2px rgba(255,184,0,.5);}
.avatar-ring-sm.avatar-ring-silver{box-shadow:0 0 0 2px #C0C0C0;}
.avatar-ring-sm.avatar-ring-bronze{box-shadow:0 0 0 2px #CD7F32;}
/* 純 box-shadow、冇動畫 → 唔需要 prefers-reduced-motion 分支 */

/* ---- ② 徽章小圖示（UI.badgeIconsHtml）：跟住文字排，唔撐高行高 ---- */
.hoku-badge-mini{vertical-align:-4px;margin-left:3px;flex:none;}

/* ---- ③ 人物列頭像：40px → 56px（append 覆寫上面 .person-row-avatar，唔改既有 rule） ---- */
.person-row-avatar{width:56px;height:56px;}
/* 全身造型放喺圓框：輕微內縮，避免圓周切到角色嘅腳
   （full 模式 .avatar-stack 冇 inline transform，所以呢條蓋得過） */
.person-row-avatar .avatar-stack{transform:scale(.9);}
.person-row-avatar-tap{cursor:pointer;}
.person-row-avatar-tap:focus-visible{outline:2px solid var(--brand);outline-offset:3px;}
.person-row-badges{display:inline-flex;align-items:center;}

/* ---- ④ Header 頭像：>600px 92px→148px、≤600px 52px→84px（約 1.6×） ---- */
.header-avatar{width:148px;height:148px;}
.header-avatar .avatar-stack{transform:scale(.9);}
/* 唔用 cover：上載頭像／造型都唔可以被圓框切走（造型層本身已經係 contain） */
.header-avatar img{object-fit:contain;}
.header-avatar-tap{cursor:pointer;}
.header-avatar-tap:focus-visible{outline:2px solid var(--brand);outline-offset:3px;}
@media (max-width:600px){
  .header-avatar{width:84px;height:84px;}
}

/* ---- ⑤ 放大看卡（UI.avatarModal）：大圖 min(70vw,320px)＋名／等級／統計 ---- */
.avatar-zoom{display:flex;flex-direction:column;align-items:center;gap:10px;text-align:center;}
.avatar-zoom-stage{display:flex;align-items:center;justify-content:center;}
.avatar-zoom-frame{
  display:flex;align-items:center;justify-content:center;
  width:min(70vw,320px);height:min(70vw,320px);
  border-radius:50%;overflow:hidden;background:var(--surface);
}
.avatar-zoom-name-row{display:flex;align-items:center;justify-content:center;gap:6px;flex-wrap:wrap;}
.avatar-zoom-name{font-size:18px;font-weight:900;line-height:1.35;}
.avatar-zoom-badges{display:inline-flex;align-items:center;}
.avatar-zoom-meta{display:flex;justify-content:center;}
.avatar-zoom-stats{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 20px;}
.avatar-zoom-stat{display:flex;flex-direction:column;align-items:center;min-width:72px;}
.avatar-zoom-stat-k{font-size:12px;color:var(--ink-soft);}
.avatar-zoom-stat-v{font-size:16px;font-weight:900;}

/* ============================================================================
   v6.7：換裝間 #/dressup（public/js/pages/dressup.js）
   ⚠️ 全部喺檔尾 append，唔改上面任何既有規則；class 一律 dressup- 開頭。
   ① 大預覽：容器最少 55vh、scene 背景層照出（full 模式）、唔 overflow:hidden 切腳；
   ② 格仔區跟 shop.js：repeat(auto-fill,minmax(128px,1fr))；
   ③ 底部掣 min-height 44px（手機 tap target）。
   ============================================================================ */

/* ---- ① 大預覽（最少 55vh；光環由 UI.ringWrap 套喺外面） ---- */
.dressup-preview{
  display:flex;align-items:center;justify-content:center;
  min-height:55vh;max-width:100%;padding:6px 0 2px;
}
.dressup-stage{display:flex;align-items:center;justify-content:center;max-width:100%;}
.dressup-frame{
  display:flex;align-items:center;justify-content:center;
  width:min(78vw,58vh,420px);height:min(78vw,58vh,420px);
  border-radius:20px;background:var(--surface);
}
.dressup-caption{
  text-align:center;font-size:13px;line-height:1.6;color:var(--ink-soft);
  margin:6px 0 14px;
}

/* ---- ② 格仔區：同 shop.js 一樣（128px 起，375px 唔會橫向滾動） ---- */
.dressup-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(128px,1fr));gap:10px;}

/* ---- ③ 格仔：單件縮圖＋名＋「使用中」 ---- */
.dressup-cell{
  position:relative;display:flex;flex-direction:column;align-items:center;gap:6px;
  background:#fff;border:2px solid var(--line);border-radius:16px;padding:10px 8px;
  font-family:inherit;color:inherit;cursor:pointer;min-width:0;width:100%;min-height:44px;
}
.dressup-cell-on{border-color:var(--brand);box-shadow:inset 0 0 0 2px var(--brand);}
.dressup-thumb{
  width:100%;height:96px;display:flex;align-items:center;justify-content:center;
  background:var(--surface);border-radius:12px;overflow:hidden;
}
.dressup-thumb img{width:100%;height:100%;object-fit:contain;display:block;}
.dressup-cell-name{
  font-weight:800;font-size:13.5px;line-height:1.3;text-align:center;
  overflow-wrap:anywhere;word-break:break-word;width:100%;min-width:0;
}
.dressup-use-tag{
  font-size:11px;font-weight:900;line-height:1;color:#fff;background:var(--brand);
  border-radius:999px;padding:3px 9px;
}

/* ---- ④ 底部主掣：儲存造型／還原 ---- */
.dressup-actions{display:flex;gap:10px;flex-wrap:wrap;}
.dressup-actions>.btn{flex:1 1 140px;min-width:0;min-height:44px;}

@media (max-width:600px){
  .dressup-frame{width:min(84vw,52vh,420px);height:min(84vw,52vh,420px);}
  .dressup-thumb{height:88px;}
}

/* ============================================================================
   v6.9（2026-10-04）：手機 UI 死症修復（Prompt 2：U1／U2／U3／U4／U5／U7／U8）
   ＋ R46「#/badges 未解鎖徽章睇唔清」。
   全部喺檔尾 append：上面任何既有 rule 一字未改，同優先度時一律後寫者生效。
   ⚠️ 44px 觸控熱區規矩一律保留 —— .btn-sm／.tab（!important）／#app-nav .nav-item
      嘅 min-height:44px 喺本段一個字都冇郁；本段亦冇任何 transform:scale 縮控件。
   ============================================================================ */

/* ---------------------------------------------------------------------------
   U3：登入／註冊頁品牌標記（login.js:147、register.js:40 嘅 .brand-mark-lg）
   現況：v5.4j（:1722）已經取消藍底，但盒仍然固定 64×64，而 login.js 張 img 帶
        width="128" height="128" 屬性 → 盒同圖兩套尺吋（圖被壓、邊位出 halo）。
   改法：盒改成「跟圖自縮」（width/height auto、padding 0、底色透明），
        圖直接出 96px；≤480px 收 64px（見下面 U1 段）。
   :418 同 :1722 兩條舊 rule 冇改，呢兩條只係後寫者覆蓋。
   --------------------------------------------------------------------------- */
.brand-mark-lg{
  width:auto;height:auto;padding:0;border-radius:0;
  background:transparent;box-shadow:none;overflow:visible;
}
.brand-mark-lg img{width:96px;height:96px;display:block;object-fit:contain;}

/* ---------------------------------------------------------------------------
   U4：換裝間 8 個 pill 分頁（dressup.js paintTabs()）喺 360px 屈 2–3 行
   → 改成一條橫向滑動 rail（唔淮 wrap、scrollbar 隱藏但照樣可以掃）。
   ⚠️ dressup.js 嘅 tabsHost 係一個無 class 嘅 div，亦係 .dressup-preview 之後嘅
      兄弟 → 用 `~ div > .tabs` 精準定位，其他頁嘅 .tabs 完全唔會受影響。
   ⚠️ .tab 嘅 min-height:44px !important（:2005）冇郁，只加 flex:0 0 auto ＋ nowrap。
   --------------------------------------------------------------------------- */
.dressup-preview ~ div > .tabs{
  display:flex;flex-wrap:nowrap;width:100%;max-width:100%;
  overflow-x:auto;overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;
  scrollbar-width:none;
}
.dressup-preview ~ div > .tabs::-webkit-scrollbar{display:none;}
.dressup-preview ~ div > .tabs > .tab{flex:0 0 auto;white-space:nowrap;}

/* ---------------------------------------------------------------------------
   U5：換裝間大預覽 sticky（捲格仔時大圖常駐）
   祖先鏈：#app → body → html，全部冇 overflow 捲動容器（html,body 係
   overflow-x:clip，:1871；clip 唔會建立捲動容器，所以唔會攔截 sticky）→ sticky 有效。
   ⚠️ 學生頁有固定頂欄 #app-nav（position:fixed、z-index:60、高約 54px），
      冇讓開就會令大圖縮入 nav 底下 → body.has-nav 時 top 用 62px（54 ＋ 8 空隙）。
   ≤600px：min-height 55vh → 46vh（:4151 嗰條舊 rule 冇改，呢條後寫者覆蓋）。
   --------------------------------------------------------------------------- */
.dressup-preview{position:sticky;top:8px;z-index:5;background:var(--bg);}
body.has-nav .dressup-preview{top:62px;}
@media (max-width:600px){
  .dressup-preview{min-height:46vh;}
}

/* ---------------------------------------------------------------------------
   U1 ＋ U2：≤480px 全局緊湊檔（登入／註冊一屏化 ＋ 每頁短一截）
   ⚠️ 兩份清單有重疊（U1 卡 padding 14／field margin 10、U2 卡 padding 16／
      field margin 12）→ 收窄成：全局跟 U2（16／12），登入卡 .auth-wrap 內跟 U1
      （14／10）。兩邊都逐字做到，亦講清楚邊個 scope 生效。
   ⚠️ 唔縮任何 44px 熱區：.btn 只加 padding 唔減 min-height（下面 .btn 條
      min-height:44px 照舊生效），.tab／.btn-sm／nav-item 冇碰。
   --------------------------------------------------------------------------- */
@media (max-width:480px){
  /* ---- U2：全局緊湊檔 ---- */
  .card{padding:16px;}
  .btn{padding:11px 20px;}
  .field{margin-bottom:12px;}
  .input,.field input[type=text],.field input[type=password],
  .field input[type=number],.field select,.field textarea{padding:10px 14px;}

  /* ---- U1：登入／註冊卡（.auth-wrap 亦包括 landing 內嵌嗰份登入卡） ---- */
  .auth-wrap{margin:8px auto 0;}
  .auth-logo{margin-bottom:12px;}
  .auth-logo h1{font-size:18px;margin:0 0 2px;}
  .brand-mark-lg{margin-bottom:8px;}
  .brand-mark-lg img{width:64px;height:64px;}
  .auth-wrap .card{padding:14px;}
  .auth-wrap .field{margin-bottom:10px;}
  .auth-wrap .field label{margin-bottom:4px;}
  .auth-wrap .btn-lg{padding:11px 22px;font-size:16px;}
  .auth-wrap .tabs{margin-bottom:10px;}
  .auth-wrap .owner-entry{margin-top:18px;}

  /* ---- landing 版登入卡（#/login 未登入時 render 嘅就係 landing）：外距都收 ---- */
  .landing-login{padding:12px 14px 14px;}
  .landing-login .auth-wrap{margin:0 auto;}
  .landing-login .auth-logo{margin-bottom:10px;}
  .landing-login .owner-entry{margin-top:14px;}
  /* 宣傳圖區 28vh → 24vh（覆寫 :2052 ≤640px 同 :1656 ≤380px 兩條，唔改佢哋）：
     讓返約 26px 高度俾登入卡，令 360×640 一屏見晒有餘裕（唔係「剛剛好貼底」）。
     768px 以上完全唔關事（呢條只喺 ≤480px 生效）。 */
  .landing-sales{height:24vh;height:24dvh;min-height:110px;}
}

/* 短螢幕（360×640 一類）先收埋品牌標語：高身電話（例如 390×844）保留。
   .auth-logo p = login.js 嘅品牌 tagline「知識入庫，星光引路。Let's HOKU!」，
   收埋只係版面取捨，唔影響任何功能（標語喺 landing 卡底另有位置）。 */
@media (max-width:480px) and (max-height:720px){
  .auth-logo p{display:none;}
}

/* ---------------------------------------------------------------------------
   U7：長句迫行（原本只做咗 h1,h2，:2044）
   · text-wrap:balance → 卡片標題／選項卡／人名（Chromium／Safari 支援；
     Firefox 會靜靜忽略，唔會壞版）
   · overflow-wrap:anywhere → 長名（頂欄用戶名／團隊名連結／龍虎榜卡片名）
   --------------------------------------------------------------------------- */
.card h3,.choice,.person-row-name{text-wrap:balance;}
.header-name,.person-row-name,a[href^="#/team/"],.teams-card-name{overflow-wrap:anywhere;}

/* ---------------------------------------------------------------------------
   U8：龍虎榜 ⇄ 直排卡片（CSS 部分；teams.js 由另一個 agent 加容器）
   契約（一定要跟呢套 class 名）：
     .teams-cards                 容器（一行一張卡）
     .teams-card                  每行（.is-me ＝ 自己隊）
     .teams-card-rank             名次（.r1／.r2／.r3 ＝ 金／銀／銅）
     .teams-card-main             中間（名 ＋ 徽章）
     .teams-card-name             隊名
     .teams-card-badges           徽章細 icon 列
     .teams-card-stats            右邊數字
   >600px 隱藏卡片、≤600px 隱藏 .teams-table（原本嘅 <table>）。
   ⚠️ 呢一批全部係新 class，未有任何 JS 用；表未轉之前對現有版面零影響。
   --------------------------------------------------------------------------- */
.teams-cards{display:none;}
.teams-card{
  display:flex;align-items:center;gap:10px;min-width:0;
  background:var(--card);border:1px solid var(--card-border);border-radius:16px;
  box-shadow:var(--card-shadow);padding:10px 12px;cursor:pointer;
}
.teams-card.is-me{border-color:var(--brand);background:var(--brand-soft);}
.teams-card-rank{
  flex:none;display:inline-flex;align-items:center;justify-content:center;
  min-width:30px;height:30px;padding:0 6px;border-radius:999px;
  background:var(--surface);color:var(--ink-soft);
  font-size:13px;font-weight:900;line-height:1;font-variant-numeric:tabular-nums;
}
.teams-card-rank.r1{background:var(--gold,#FFB800);color:#4A2E00;}
.teams-card-rank.r2{background:var(--silver,#9AA6B2);color:#fff;}
.teams-card-rank.r3{background:var(--bronze,#C97A3A);color:#fff;}
.teams-card .avatar-sm,
.teams-card .person-row-avatar{width:40px;height:40px;}
.teams-card-main{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px;}
.teams-card-name{font-size:14.5px;font-weight:900;line-height:1.35;}
.teams-card-badges{display:inline-flex;align-items:center;gap:4px;flex-wrap:wrap;min-width:0;}
.teams-card-badges img{width:18px;height:18px;display:block;}
.teams-card-stats{
  flex:none;margin-left:auto;text-align:right;min-width:0;
  font-size:12.5px;line-height:1.35;color:var(--ink-soft);
  font-variant-numeric:tabular-nums;
}
.teams-card-stats b{display:block;font-size:15px;font-weight:900;color:var(--ink);}
@media (max-width:600px){
  .teams-cards{display:flex;flex-direction:column;gap:10px;}
  .teams-table{display:none;}
}

/* ---------------------------------------------------------------------------
   R46：`#/badges` 未解鎖徽章（class 由 badges.js 注入嘅 <style> 定義：
   .hoku-badge-cell.locked .hoku-badge-img{filter:grayscale(1);opacity:.45}）
   問題：9 張 badge PNG 嘅不透明像素平均亮度 114–154，乘 .45 再疊喺白卡上面
         → 合成亮度約 208（同白底只差 47），睇落近乎空白。
   改法：唔再靠「近乎透明」表達未解鎖 —— 提高到 .7 並用 grayscale(.85)
         （保留少少色相）＋ brightness(.95)，合成亮度約 176（同白底差 79，
         約為已解鎖徽章 105 嘅 75%）；「未解鎖」靠原本已經有嘅虛線框、
         右上角鎖頭 icon、灰字交代。
   ⚠️ badges.js 注入嘅 <style> 喺 style.css 之後入 head，同一個 selector
      佢會贏 → 呢度一定要 !important 才蓋得過（唔改 badges.js 一個字）。
   --------------------------------------------------------------------------- */
.hoku-badge-cell.locked .hoku-badge-img{
  filter:grayscale(.85) brightness(.95) !important;
  opacity:.7 !important;
}

/* ============================================================================
   v6.10（2026-10-04）：換裝間遊戲化全改版
   （IMPLEMENTATION_QUEUE_2026-10-04.md Prompt 4 第 2／3／4 點
     ＋ 兩個小修正：預覽光環圓角、shop.js REASON_LABEL 嗰句屬 JS 唔關 CSS 事）
   全部喺檔尾 append：上面任何既有 rule 一字未改，同優先度時一律後寫者生效。
   ⚠️ 換裝間嘅 DOM 改咗（public/js/pages/dressup.js）：
      · 8 個 pill tab 冇咗（.tabs 一個都唔再出）→ v6.9 嗰條
        `.dressup-preview ~ div > .tabs{overflow-x:auto;flex-wrap:nowrap...}`
        喺換裝間已經冇對象（其他頁 .tabs 完全冇影響，佢仍然生效）；
        「唔准 wrap、改橫向滑動」嘅意圖由下面 .dressup-slotrail 接手。
      · slot node rail 放喺 `.dressup-preview`（sticky 盒）**入面** →
        sticky 嘅 containing block 仍然係 #app（成頁），捲格仔區時大圖同 rail 一齊常駐。
   ⚠️ 44px 觸控熱區一律保留：.dressup-slotnode 44×44、.dressup-preset min-height 56px、
      .dressup-actions > .btn min-height 44px（:4192 原 rule 冇郁）。
   ============================================================================ */

/* ---------------------------------------------------------------------------
   ① 大預覽：同一個 sticky 盒入面多咗 rail（>600px 出右邊、≤600px 落正下方一行）
   :4151 同 :4244／:4247 嗰幾條 .dressup-preview 一字未改，呢度只係後寫者覆蓋：
   flex-wrap:wrap ＋ gap → rail 唔夠位就自動跌去大圖下面一行（≤600px 必然如此）。
   --------------------------------------------------------------------------- */
.dressup-preview{flex-wrap:wrap;gap:6px 14px;}
.dressup-stage{flex:0 0 auto;}

/* ---- rail 外殼：>600px 直立（貼大圖右邊）；≤600px 橫排（大圖正下方） ---- */
.dressup-slotrailwrap{
  display:flex;align-items:center;justify-content:center;
  flex:0 0 auto;max-width:100%;min-width:0;padding:4px;
}
/* 8 個 node × 44px ＋ 7 個 8px 空隙 = 394px → 360px 機一定要橫向滑動（同 U4 一樣做法：
   唔准 wrap、scrollbar 隱藏但照樣可以掃），頁面本身唔會有橫向滾動。 */
.dressup-slotrail{
  display:flex;align-items:center;gap:8px;
  margin:0;padding:6px 4px;max-width:100%;min-width:0;
  overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;
}
.dressup-slotrail::-webkit-scrollbar{display:none;}

/* ---- 圓形 slot node（RPG 角色資訊窗感：白底圓框、幼線連住、名牌） ---- */
.dressup-slotnode{
  position:relative;flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:3px;
  min-width:44px;min-height:44px;padding:0;margin:0;border:0;background:none;
  font-family:inherit;color:var(--ink-soft);cursor:pointer;
}
.dressup-slotnode-ico{
  display:flex;align-items:center;justify-content:center;flex:none;
  width:44px;height:44px;border-radius:50%;
  background:#fff;border:2px solid var(--line);
  font-size:20px;line-height:1;
}
.dressup-slotnode-label{font-size:11px;font-weight:800;line-height:1.2;white-space:nowrap;}
.dressup-slotnode:hover .dressup-slotnode-ico{border-color:var(--brand);}
.dressup-slotnode:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:14px;}
.dressup-slotnode.is-on .dressup-slotnode-ico{
  border-color:var(--brand);background:var(--brand-soft);
  box-shadow:0 0 0 3px rgba(42,92,232,.22);
}
.dressup-slotnode.is-on .dressup-slotnode-label{color:var(--brand);}
.dressup-slotnode[aria-pressed="true"] .dressup-slotnode-ico{background:var(--brand-soft);}
/* 幼線：默認（≤600px 橫排）＝左右相連，線喺圓心高度（44 ÷ 2 = 22） */
.dressup-slotnode::before{
  content:'';position:absolute;left:-9px;top:22px;width:9px;height:2px;background:var(--line);
}
.dressup-slotnode:first-child::before{content:none;}

/* ---- >600px：rail 變直立（avatar 右邊），名牌改放圓框右邊 → 圓形上下連成一線 ---- */
@media (min-width:601px){
  .dressup-slotrail{
    flex-direction:column;align-items:flex-start;gap:10px;
    overflow:visible;padding:6px 2px;
  }
  .dressup-slotnode{flex-direction:row;align-items:center;gap:10px;}
  .dressup-slotnode::before{left:21px;top:-11px;width:2px;height:11px;}
}

/* ---------------------------------------------------------------------------
   ② 主題套裝（4 張掣卡：騎士／魔法／公主／太空）
   卡高 ≥56px；active（而家著住嗰套）用 brand 色框＋「使用中」tag。
   --------------------------------------------------------------------------- */
.dressup-presets{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px;}
.dressup-preset{
  display:flex;align-items:center;gap:10px;width:100%;min-width:0;min-height:56px;
  background:#fff;border:2px solid var(--line);border-radius:16px;padding:10px 12px;
  font-family:inherit;color:inherit;cursor:pointer;text-align:left;
}
.dressup-preset:hover{border-color:var(--brand);}
.dressup-preset:focus-visible{outline:2px solid var(--brand);outline-offset:2px;}
.dressup-preset-ico{font-size:22px;line-height:1;flex:none;}
.dressup-preset-txt{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-width:0;}
.dressup-preset-name{font-weight:900;font-size:14.5px;line-height:1.3;}
.dressup-preset-sub{font-size:11.5px;line-height:1.3;color:var(--ink-soft);overflow-wrap:anywhere;}
.dressup-preset .dressup-use-tag{flex:none;}
.dressup-preset.is-on{
  border-color:var(--brand);background:var(--brand-soft);
  box-shadow:inset 0 0 0 2px var(--brand);
}

/* ---------------------------------------------------------------------------
   ③ 「試著中・尚未儲存」提示（dressup-actions 上面一行）
   --------------------------------------------------------------------------- */
.dressup-unsaved{
  display:inline-flex;align-items:center;gap:6px;margin:0 0 10px;
  background:var(--gold-soft);color:var(--gold-dark);
  border:1px solid rgba(201,143,0,.35);border-radius:999px;
  padding:5px 12px;font-size:12.5px;font-weight:800;line-height:1.3;
}

/* ---------------------------------------------------------------------------
   ④ 修正：換裝間大預覽嘅光環睇唔到
   成因：大預覽係圓角方卡（.dressup-frame 20px），而光環 wrapper
        span.avatar-ring（:4093）係 **border-radius:50%** —— 4px 嘅 box-shadow
        沿住「圓形」走，但卡係方形 → 光環同卡邊重合／縮入卡內，睇落等於冇。
   改法：只喺換裝間預覽入面，令 ring wrapper 跟返方卡圓角（卡 20px ＋ 環 4px → 22px）。
   只係 border-radius 一條，冇改任何 .avatar-ring 既有 rule（其他地方照係圓形）。
   --------------------------------------------------------------------------- */
.dressup-preview .avatar-ring{border-radius:22px;}

/* ---------------------------------------------------------------------------
   ⑤ ≤600px 收尾：rail 佔足一行、格仔區同 preset 保持單欄可讀
   --------------------------------------------------------------------------- */
@media (max-width:600px){
  .dressup-slotrailwrap{flex:1 1 100%;width:100%;}
  .dressup-presets{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));}
  .dressup-preset{padding:9px 10px;}
}

/* ============================================================================
   v6.12（2026-10-04）按鈕族譜統一：全站「可按嘅嘢」同一套 look & feel
   （app.js／coin.js／shop.js 嘅 v6.11 係帳戶守衛，同 CSS 呢個編號系列無關；
     CSS 由 v6.10 直接跳 v6.12，避免同 v6.11 撞名。）

   背景（owner 原話）：「pls check all buttons style in the app, color can be
   different size can differ too, but the style shud be the same look n feel!」
   —— 呢個 app 除咗 .btn 族之外，仲有幾十個自製可按元件（.count-btn／.grade-pill／
   .hw-go／.master-go／.trial-go／.tab／.chip／.shop-item／.dressup-*／.teams-card／
   .own-*／.q-flag／.mf-pager-btn…），各有各嘅圓角、字重、撳落去嘅反應同 disabled 觀感。

   呢一段只做「統一」，唔做「重新設計」：
     · 唔郁 .btn 族（.btn／.btn-sm／.btn-lg／.btn-block／.btn-soft／.btn-ghost／
       .btn-mint／.btn-brand／.btn-coral／.btn-mustard／.btn-sage／.btn-blue）——基準。
     · 唔郁任何顏色語意（藍＝品牌、薄荷＝成功、金＝獎勵、珊瑚＝警示）。
     · 唔縮任何觸控熱區（44px 下限原封不動，只會補大唔會縮細）。

   ── 族譜：兩個角色，每個角色只有一組數值（顏色／大細照舊可以唔同）──
   G1「立體掣」（提交、開始、購買、升級、上載、選項卡）
        底部立體邊 4px：box-shadow:0 4px 0 0 <同色深階 或 var(--line)>
        :active：transform:translateY(4px) ＋ 立體邊收窄到 0（同 .btn 完全一致）
        字重 800、min-height 44px、圓角 = pill 或 14–16px
   G2「輕撳掣」（分頁 tab、圖示掣、工具列細掣、導覽卡、整行／整塊點擊區）
        冇立體邊 —— 呢類元件係「切換／跳頁」而唔係「提交」，硬加 3D 邊會同
        .tab.active 嘅白色 pill 語言打架
        :active：transform:translateY(1px)（hover／選中色照舊）
        字重 800、min-height 44px、圓角 = pill 或 12–16px
   G1／G2 共通 disabled：opacity .55、box-shadow 收起、transform:none、
        cursor:not-allowed（.btn:disabled 本身係灰底版，唔郁佢）。

   ── 圓角尺度：全站只准呢三級，唔准再出現第 4 種數值 ──
        pill 999px → 行內掣／選擇 pill（.btn 族、.hw-go、.master-go、.trial-go、
                     .count-btn、.grade-btn、.chip、.grade-pill、.m-child、.tab…）
        14–16px    → 選項卡／整寬卡（.choice、.pick-card、.m-seg-btn、.reg-pick、
                     .plan-card、.q-opt、.dressup-preset、.dressup-cell、.shop-item…）
        12px       → 工具列細掣／圖示掣（.q-flag、.mf-pager-btn、.bell、
                     .own-drawer-x、.own-menu-btn、.own-todo button、.own-cell）

   ⚠️ 本段冇改上面任何一條既有 rule，全部係檔尾「後寫者覆蓋」；
      !important 只有一處（.chip 嘅 min-height，理由寫喺該行）。
   ============================================================================ */

:root{
  --hoku-press-3d:4px;    /* G1 立體邊厚度＝撳落去下沉距離（對齊 .btn 基準） */
  --hoku-press-soft:1px;  /* G2 輕撳下沉距離 */
  --hoku-dim:.55;         /* disabled 觀感：全站同一個透明度和 */
}

/* ---------------------------------------------------------------------------
   ① G1：立體邊由 3px 統一升到 4px（同 .btn 一樣），撳落去一律沉 4px 到「貼地」
   --------------------------------------------------------------------------- */

/* 1a 品牌藍實色掣：.hw-go（學生主頁每份卷）／.master-go（題庫每份卷） */
.hw-go,.master-go{box-shadow:0 var(--hoku-press-3d) 0 0 var(--brand-dark,#1E46B8);}
.hw-go:active,.master-go:active{
  transform:translateY(var(--hoku-press-3d));
  box-shadow:0 0 0 0 var(--brand-dark,#1E46B8);
}

/* 1b 薄荷實色掣：.trial-go／.trial-send（14 日試用漏斗）
      （.trial-card .btn 係 .btn 族嘅主題變體，按規矩唔郁。） */
.trial-go,.trial-send{box-shadow:0 var(--hoku-press-3d) 0 0 var(--mint-dark,#0B8F63);}
.trial-go:active,.trial-send:active{
  transform:translateY(var(--hoku-press-3d));
  box-shadow:0 0 0 0 var(--mint-dark,#0B8F63);
}

/* 1c 白底／淺底選項卡：.choice（答題選項）／.pick-card（科目）／.grade-pill（課題、
      年級）／.m-child（仔女）／.m-seg-btn（學生三大分頁）／.reg-pick（註冊身份）／
      .plan-card（訂閱方案）／.q-opt（未升級做 .choice 之前嘅原始選項列） */
.choice,.pick-card,.grade-pill,.m-child,.m-seg-btn,.reg-pick,.plan-card,.q-opt{
  box-shadow:0 var(--hoku-press-3d) 0 0 var(--line,#E2E8F0);
}
.choice:active,.pick-card:active,.grade-pill:active,.m-child:active,
.m-seg-btn:active,.reg-pick:active,.plan-card:active,.q-opt:active{
  transform:translateY(var(--hoku-press-3d));
  box-shadow:0 0 0 0 var(--line,#E2E8F0);
}
/* 已選中嘅立體邊同樣 4px —— 只改厚度，顏色語意一律唔動 */
.pick-card.on{box-shadow:0 var(--hoku-press-3d) 0 0 var(--brand,#2A5CE8);}
.grade-pill.on,.m-seg-btn.active,.m-child.on{
  box-shadow:0 var(--hoku-press-3d) 0 0 var(--brand-dark,#1E46B8);
}
.reg-pick.on,.reg-pick.sel,.reg-pick[aria-checked="true"],
.plan-card.on,.plan-card.sel,.plan-card[aria-checked="true"]{
  box-shadow:0 var(--hoku-press-3d) 0 0 var(--brand,#2A5CE8);
}
/* 撳「已選中」嘅卡：貼地時要收成佢自己嘅選中色（唔係 var(--line)） */
.pick-card.on:active,.reg-pick.on:active,.reg-pick.sel:active,
.plan-card.on:active,.plan-card.sel:active{box-shadow:0 0 0 0 var(--brand,#2A5CE8);}
.grade-pill.on:active,.m-seg-btn.active:active,.m-child.on:active{
  box-shadow:0 0 0 0 var(--brand-dark,#1E46B8);
}

/* ---------------------------------------------------------------------------
   ② G1：本來係「平面」嘅真按鈕 → 補返族譜嘅立體邊、撳落去反應、字重 800
   --------------------------------------------------------------------------- */

/* 2a 題數／年級選擇 pill（學生主頁、家長設定、admin）：白底＋淺線，
      立體邊用線色（同 .choice／.grade-pill 嘅白底掣一樣，唔搶色）；
      選中（.active）用品牌深階，同 .grade-pill.on 同一語言 */
.count-btn,.grade-btn{
  font-weight:800;                       /* 原 700 → 800，同 .btn／.choice 一致 */
  box-shadow:0 var(--hoku-press-3d) 0 0 var(--line);
  transition:transform .06s ease, box-shadow .06s ease,
             border-color .15s ease, background .15s ease, color .15s ease;
}
.count-btn:active,.grade-btn:active{
  transform:translateY(var(--hoku-press-3d));
  box-shadow:0 0 0 0 var(--line);
}
.count-btn.active,.grade-btn.active{box-shadow:0 var(--hoku-press-3d) 0 0 var(--brand-dark);}
.count-btn.active:active,.grade-btn.active:active{
  transform:translateY(var(--hoku-press-3d));
  box-shadow:0 0 0 0 var(--brand-dark);
}

/* 2b 排序題字詞 chip：底 #E8F0FE、邊係品牌藍 → 立體邊用同 .btn-soft 一樣嘅淺藍
      #D8E3FB（同系色，唔會令一片字詞變成一片深藍）；熱區同時補到 44px */
.chip{
  font-weight:800;                       /* 原 700 → 800 */
  box-shadow:0 var(--hoku-press-3d) 0 0 #D8E3FB;
  min-height:44px !important;            /* ⚠️ 全段唯一 !important：components.js 用
                                            inline style 寫死 min-height:40px（低過 44px
                                            觸控下限）。作者宣告嘅 !important 係唯一
                                            可以蓋過 inline 普通宣告嘅手段，所以留在。 */
  transition:transform .06s ease, box-shadow .06s ease, background .15s ease;
}
.chip:active{transform:translateY(var(--hoku-press-3d));box-shadow:0 0 0 0 #D8E3FB;}

/* 2c 團隊大圖上嘅兩粒上載掣（.team-hero-up）：底邊用深色半透明，唔搶 banner 相；
      按落去一樣沉 4px 貼地 */
.team-hero-up{box-shadow:0 var(--hoku-press-3d) 0 0 rgba(15,23,42,.22);}
.team-hero-up:active{
  transform:translateY(var(--hoku-press-3d));
  box-shadow:0 0 0 0 rgba(15,23,42,.22);
}

/* 2d 換裝間主題套裝卡（騎士／魔法／公主／太空）：係「揀一套」→ G1。
      .is-on 本身有 inset 品牌框，要同立體邊並存（所以寫成兩段陰影） */
.dressup-preset{box-shadow:0 var(--hoku-press-3d) 0 0 var(--line);}
.dressup-preset:active{
  transform:translateY(var(--hoku-press-3d));
  box-shadow:0 0 0 0 var(--line);
}
.dressup-preset.is-on{
  box-shadow:inset 0 0 0 2px var(--brand), 0 var(--hoku-press-3d) 0 0 var(--brand);
}
.dressup-preset.is-on:active{
  transform:translateY(var(--hoku-press-3d));
  box-shadow:inset 0 0 0 2px var(--brand), 0 0 0 0 var(--brand);
}

/* 2e 註冊身份卡／學習模式卡（.mode-card）同 .subject-card：都係「揀一個」→ G1。
      hover 由「浮起」改成「只換邊色、保住立體邊」，同 .pick-card／.grade-pill
      完全一致 —— 撳落去先沉，唔會再由 -2px 跳到 +4px 嘅大跳 */
.mode-card,.subject-card{
  box-shadow:0 var(--hoku-press-3d) 0 0 var(--line);
  transition:transform .06s ease, box-shadow .06s ease,
             border-color .15s ease, background .15s ease;
}
.mode-card:hover,.subject-card:hover{
  transform:none;
  box-shadow:0 var(--hoku-press-3d) 0 0 var(--line);
}
.mode-card:active,.subject-card:active{
  transform:translateY(var(--hoku-press-3d));
  box-shadow:0 0 0 0 var(--line);
}
.mode-card.active{box-shadow:0 var(--hoku-press-3d) 0 0 var(--brand);}
.mode-card.active:hover{box-shadow:0 var(--hoku-press-3d) 0 0 var(--brand);}
.mode-card.active:active{
  transform:translateY(var(--hoku-press-3d));
  box-shadow:0 0 0 0 var(--brand);
}

/* ---------------------------------------------------------------------------
   ③ G2 輕撳掣：分頁／chip 以外嘅切換、圖示、工具列、導覽卡、整行點擊區
      統一 transition、字重、圓角入尺度，撳落去一律沉 1px（唔加立體邊）。
      範圍：.tab（全站分頁）／.q-flag（考試插旗）／.mf-pager-btn（會員／好友分頁）／
            .bell（通知鐘）／.landing-jump（首頁跳去登入）／.own-cell（owner 題庫矩陣格）／
            .own-drawer-x（owner 側欄關閉）／.m-rangechip-x（家長範圍 chip 嘅 ✕）／
            .dressup-slotnode（換裝間部件 rail）／.dressup-cell（換裝間造型格）／
            .shop-item（商店貨品卡）／.teams-card（團隊卡）／.avatar-pick（頭像選擇）／
            .header-avatar-tap／.person-row-tap／.person-row-avatar-tap／.row-avatar-tap（頭像／
            整行／整卡點擊區）
   --------------------------------------------------------------------------- */
.tab,.q-flag,.mf-pager-btn,.bell,.landing-jump,.own-cell,.own-drawer-x,
.m-rangechip-x,.dressup-slotnode,.dressup-cell,.shop-item,.teams-card,.avatar-pick,
.header-avatar-tap,.person-row-tap,.person-row-avatar-tap,.row-avatar-tap{
  transition:transform .08s ease, background .15s ease, border-color .15s ease,
             box-shadow .12s ease, color .15s ease;
}
.tab:active,.q-flag:active,.mf-pager-btn:active,.bell:active,.landing-jump:active,
.own-drawer-x:active,.m-rangechip-x:active,.dressup-slotnode:active,
.dressup-cell:active,.shop-item:active,.teams-card:active,.avatar-pick:active,
.header-avatar-tap:active,.person-row-tap:active,.person-row-avatar-tap:active,
.row-avatar-tap:active{transform:translateY(var(--hoku-press-soft));}

/* 3a 分頁字重（原 700 → 800）＋ 圖示掣入 12px 圓角一級、補同 .own-drawer-x
      一樣嘅 hover 底（本身背景透明，唔補 hover 就完全冇「可撳」提示） */
.tab,.tab.active{font-weight:800;}
.bell{border-radius:12px;}
.bell:hover{background:var(--surface);}
.own-drawer-x{border-radius:12px;}

/* ---------------------------------------------------------------------------
   ④ Owner 控制台：四粒唔屬 .btn 族嘅掣（.own-cell／.own-todo button／
      .own-menu-btn／.own-drawer-x）補返立體邊。
      ⚠️ Owner 頁有一條既有「頁面級」規則
            body.page-owner button:not(:disabled):active{transform:translateY(3px);
                                                          box-shadow:none;}
         （specificity 0,3,2 勝過 .own-cell:active，我唔郁佢），所以呢度嘅立體邊
         一律用 3px 對齊，撳落去由嗰條規則收邊 —— console 內部一樣「沉到貼地」。
   --------------------------------------------------------------------------- */
body.page-owner .own-cell,
body.page-owner .own-todo button,
body.page-owner .own-menu-btn{box-shadow:0 3px 0 0 var(--line);}
body.page-owner .own-cell.usable{box-shadow:0 3px 0 0 #B7E7D4;}
body.page-owner .own-cell.shelf{box-shadow:0 3px 0 0 #F3E0A8;}
body.page-owner .own-cell.on{box-shadow:0 3px 0 0 var(--brand);}
body.page-owner .own-todo button.warn{box-shadow:0 3px 0 0 #FECACA;}
body.page-owner .own-todo button.gold{box-shadow:0 3px 0 0 #F3E0A8;}
/* .own-menu-btn 本來係 var(--card-shadow) 軟卡陰影 → 換成同 .btn-ghost 一樣嘅線色立體邊 */
body.page-owner .own-menu-btn{box-shadow:0 3px 0 0 var(--line);}

/* ---------------------------------------------------------------------------
   ⑤ 圓角／disabled／熱區補漏（顏色一律唔動）
   --------------------------------------------------------------------------- */

/* 5a 圓角入尺度：.grade-pill.m-topicpill 本來被後寫嘅 12px 蓋過（同族 .grade-pill
      係 14px）→ 撥返 14px；.own-cell 由 10px 入 12px 一級 */
.grade-pill.m-topicpill{border-radius:14px;}
.own-cell{border-radius:12px;}

/* 5b disabled 觀感全站一致（.btn:disabled 唔郁） */
.count-btn:disabled,.grade-btn:disabled,.chip:disabled,.tab:disabled,
.q-flag:disabled,.mf-pager-btn:disabled,.team-hero-up:disabled,.hw-go:disabled,
.master-go:disabled,.trial-go:disabled,.trial-send:disabled,.choice:disabled,
.pick-card:disabled,.grade-pill:disabled,.m-child:disabled,.m-seg-btn:disabled,
.reg-pick:disabled,.plan-card:disabled,.mode-card:disabled,.dressup-preset:disabled,
.dressup-cell:disabled,.shop-item:disabled,.own-cell:disabled,
body.page-owner .own-todo button:disabled,
body.page-owner .own-menu-btn:disabled{
  opacity:var(--hoku-dim);
  box-shadow:none;
  transform:none;
  cursor:not-allowed;
}

/* 5c 熱區補漏：.m-rangechip-x 本身只有 22×22（低過 44px 下限）。視覺零改動，
      用偽元素把熱區撐到 44×44；外層 span.m-rangechip 冇任何 handler，唔會搶點擊 */
.m-rangechip-x{position:relative;}
.m-rangechip-x::after{
  content:'';position:absolute;left:-11px;right:-11px;top:-11px;bottom:-11px;
}

/* ---------------------------------------------------------------------------
   v6.12 補遺：底部導覽（#app-nav .nav-item）
   #app-nav .nav-item 係 G2「分頁族」嘅一員（同 .tab 同一個角色），但一直冇任何
   撳落去反應 —— 同頁嘅 .tab 有、佢冇，屬同族唔一致。呢度只補 transition 同下沉 1px，
   顏色／選中狀態（.nav-item.active 品牌藍底）一律唔郁。
   （.nav-item 本身 cursor:pointer、min-height:44px、字重 800，已經合族譜。）
   --------------------------------------------------------------------------- */
#app-nav .nav-item{
  transition:transform .08s ease, background .15s ease, color .15s ease;
}
#app-nav .nav-item:active{transform:translateY(var(--hoku-press-soft));}

/* ============================================================================
   v6.13（2026-10-04）：換裝間 #/dressup 版面重做
   （借經典手遊「角色面板」嘅格局：中央角色 ＋ 左右裝備槽；配色一律跟本 app
     淺色 playful 設計系統 —— 沿用既有 CSS 變數、card 風格、44px 熱區。）
   ⚠️ 全部喺檔尾 append，上面任何既有 rule 一字未改；class 一律 dressup- 開頭。
   ⚠️ 上一版嘅 .dressup-slotrail／.dressup-slotnode（圓形 slot node rail）已冇任何
     元素再用，上面規則留住唔刪（唔准刪上面規則）；本段完全冇重用佢哋。

   ── 格局（重要，跟住改之前先睇呢段）──
   ① .dressup-panel：中央角色面板。max-width 560px 置中；min-height 46vh。
      背景做法＝inline style 放 `linear-gradient(白色漸變遮罩), url(scene_scX.png)`，
      呢度只負責 background-size:cover／center；avatar 框內嘅 scene 層由
      `.dressup-frame .avatar-layer[src*="/scene_"]` 靜咗（避免同面板背景疊兩層 scene）。
   ② .dressup-panel-body：三欄 grid `[左槽列 | 中央角色 | 右槽列]`
      （64px | 1fr | 64px）。左右槽列各 4 格垂直排；≤480px 收做
      `[48px | 1fr | 48px]` —— 仍然係三欄，絕對唔會變成上下排列。
   ③ .dressup-slot：槽格 64×64 圓角方格（≥44px 熱區；≤480px 48×48）。
      半透明白底＋幼邊框；已擁有並著緊出 img（contain）＋角仔綠點；
      未擁有／空出灰色剪影 emoji（grayscale）；選中＝品牌色邊框＋外發光。
   ④ .dressup-fnbar：面板正下方功能掣一排（.btn 族）。≤480px 兩個一行，每掣 ≥44px。
   ============================================================================ */

/* ---- ① 中央角色面板 ---- */
.dressup-panel{
  position:relative;max-width:560px;margin:0 auto 14px;
  min-height:46vh;padding:12px 14px 16px;
  display:flex;flex-direction:column;
  border:1px solid var(--card-border);border-radius:24px;
  background-color:var(--surface);
  background-size:cover;background-position:center;background-repeat:no-repeat;
  box-shadow:var(--card-shadow);
}

/* ---- ①a info bar：名 ＋ 學庫幣（撳去 #/shop）＋ 已擁有件數 ---- */
.dressup-infobar{
  display:flex;align-items:center;gap:6px 10px;flex-wrap:wrap;
  background:rgba(255,255,255,.86);border:1px solid var(--card-border);
  border-radius:999px;padding:4px 12px;margin:0 0 12px;
  box-shadow:0 1px 2px rgba(15,23,42,.05);
}
.dressup-info-name{
  font-weight:900;font-size:14.5px;line-height:1.3;
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.dressup-info-coins{
  display:inline-flex;align-items:center;gap:6px;
  min-height:44px;padding:0 4px;margin-left:auto;
  font-weight:900;font-size:15px;color:var(--ink);text-decoration:none;border-radius:999px;
}
.dressup-info-coins:hover{color:var(--brand);text-decoration:none;}
.dressup-info-coins:focus-visible{outline:2px solid var(--brand);outline-offset:2px;}
.dressup-info-value{font-variant-numeric:tabular-nums;}
.dressup-info-owned{font-size:12.5px;font-weight:800;color:var(--ink-soft);line-height:1.4;}

/* ---- ①b 三欄 grid：[左槽列 | 中央角色 | 右槽列] ---- */
.dressup-panel-body{
  flex:1 1 auto;
  display:grid;grid-template-columns:64px minmax(0,1fr) 64px;
  gap:10px;align-items:center;justify-content:center;
}
.dressup-slotcol{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;
  min-width:0;width:100%;
}

/* ---- ② 槽格（56–64px 圓角方格；本 app 熱區下限 44px） ---- */
.dressup-slot{
  position:relative;flex:none;
  width:64px;height:64px;min-width:44px;min-height:44px;
  display:flex;align-items:center;justify-content:center;
  padding:5px;border-radius:16px;
  background:rgba(255,255,255,.74);border:2px solid var(--line);
  font-family:inherit;color:inherit;cursor:pointer;overflow:hidden;
  transition:transform .08s ease, background .15s ease, border-color .15s ease,
             box-shadow .12s ease;
}
.dressup-slot:hover{border-color:var(--brand);background:rgba(255,255,255,.92);}
.dressup-slot:focus-visible{outline:2px solid var(--brand);outline-offset:2px;}
.dressup-slot:active{transform:translateY(1px);}
.dressup-slot img{width:100%;height:100%;object-fit:contain;display:block;}
.dressup-slot-ico{font-size:26px;line-height:1;filter:grayscale(1);opacity:.45;}
.dressup-slot.is-on{
  border-color:var(--brand);background:#fff;
  box-shadow:0 0 0 3px rgba(42,92,232,.22);
}
.dressup-slot.is-on .dressup-slot-ico{opacity:.8;}
.dressup-slot-dot{
  position:absolute;right:4px;bottom:4px;
  width:11px;height:11px;border-radius:50%;
  background:var(--mint);border:2px solid #fff;
  box-shadow:0 0 0 1px rgba(15,23,42,.06);
}

/* ---- ③ 中央角色：full body、contain、唔裁切 ---- */
.dressup-stage{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  min-width:0;max-width:100%;width:100%;
}
/* :4156 同 :4195（media）嗰兩條 .dressup-frame 一字未改，呢度後寫者覆蓋：
   盒改做正方形（aspect-ratio）、底色透明（scene 已經上咗面板背景）、唔裁切。 */
.dressup-frame{
  width:min(100%,300px);height:auto;aspect-ratio:1/1;
  border-radius:20px;background:transparent;
}
/* avatar 框內嘅 scene 層靜咗 —— 面板背景已經係同一張 scene（唔好疊兩層）。 */
.dressup-frame .avatar-layer[src*="/scene_"]{visibility:hidden;}
/* 光環：大預覽係圓角方卡，4px 環要跟方角（唔改上面 .avatar-ring 既有規則）。
   ⚠️ 有徽章時 UI.ringWrap 會喺 frame 外面套一個 span.avatar-ring（:4093 inline-flex、收縮至內容），
      frame 嘅 `width:min(100%,300px)` 百分比就會對住一個「靠內容定闊」嘅父盒 → 循環 → 算成 0，
      角色會變 0×0 完全睇唔到（demo01 冇徽章所以睇唔出，student01 有徽章就中）。
   做法：ring 佔滿 stage 闊度（百分比有確定值），發光改掛喺 frame 自己身上（仍然貼住方卡）。 */
.dressup-panel .avatar-ring{
  display:flex;width:100%;justify-content:center;
  border-radius:0;box-shadow:none;
}
.dressup-panel .avatar-ring-gold .dressup-frame{
  border-radius:22px;box-shadow:0 0 0 4px #FFB800,0 0 18px 4px rgba(255,184,0,.55);
}
.dressup-panel .avatar-ring-silver .dressup-frame{border-radius:22px;box-shadow:0 0 0 4px #C0C0C0;}
.dressup-panel .avatar-ring-bronze .dressup-frame{border-radius:22px;box-shadow:0 0 0 4px #CD7F32;}
.dressup-panel .dressup-caption{margin:8px 0 0;}

/* ---- ④ 功能掣一排（面板正下方；.btn 族） ---- */
.dressup-fnbar{display:flex;flex-wrap:wrap;gap:10px;margin-top:2px;}
.dressup-fnbar>.btn{flex:1 1 120px;min-width:44px;min-height:44px;padding:13px 16px;}

/* ---- ⑤ 選擇區小標題（grid 上面嗰行「👕 服裝（已擁有 5 件）」） ---- */
.dressup-gridhead{
  display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin-bottom:14px;
}
.dressup-gridhead-title{margin:0;font-size:18px;font-weight:900;line-height:1.4;}
.dressup-gridhead-sub{font-size:13px;font-weight:800;color:var(--ink-soft);}

/* ---- ⑥ ≤600px：面板貼邊（唔再額外縮 560 上限） ---- */
@media (max-width:600px){
  .dressup-panel{border-radius:20px;padding:12px;}
}

/* ---- ⑦ ≤480px：面板全闊、槽格收 48px，但照跟三欄格局（絕對唔變上下排） ---- */
@media (max-width:480px){
  .dressup-panel{min-height:46vh;padding:10px 10px 12px;}
  .dressup-panel-body{grid-template-columns:48px minmax(0,1fr) 48px;gap:6px;}
  .dressup-slot{width:48px;height:48px;border-radius:14px;padding:4px;}
  .dressup-slot-ico{font-size:20px;}
  .dressup-slotcol{gap:8px;}
  .dressup-infobar{border-radius:16px;padding:4px 10px;}
  .dressup-info-coins{margin-left:0;}
  .dressup-info-owned{margin-left:auto;}
  /* 四粒功能掣兩個一行，每粒 ≥44px */
  .dressup-fnbar>.btn{flex:1 1 calc(50% - 5px);min-height:44px;}
}

/* ============================================================================
   v6.14（2026-10-04）：#/dressup 角色腳底對齊場景地板線（配 dressup.js 嘅
   SCENE_GROUND／applyGround）
   ⚠️ 全部喺檔尾 append，上面任何既有 rule（含 v6.7／v6.9／v6.12／v6.13）一字未改。
   ⚠️ 幾何（cover 縮放、地板線喺畫面嘅 y、translateY）一律由 dressup.js 即時計，
      本段只負責「角色新位置會壓住造型名」嘅可讀性補救。

   背景：角色向下移之後，腳同小腿會落到 .dressup-caption（造型中文名）嗰一行。
        .avatar-stack 係 position:relative（定位層），會蓋過靜態嘅 caption 文字 →
        文字會俾角色遮住。呢度只係幫 caption 補一個白色藥丸底 ＋ z-index:2，
        令佢照樣清楚可讀（同本 app 其他 pill／tag 同一語言，顏色全部用既有變數）。
   ⚠️ 冇改 caption 嘅位置、冇改字級／行高、冇改 .dressup-stage 嘅任何 layout，
      所以三欄 grid 同其他頁（profile 嘅 .dressup-caption 唔受影響 —— 選擇器有
      .dressup-panel 前綴）一律照舊。
   ============================================================================ */
.dressup-panel .dressup-caption{
  position:relative;z-index:2;
  background:rgba(255,255,255,.88);
  border:1px solid var(--card-border);border-radius:999px;
  padding:2px 12px;
}

/* ============================================================================
   v6.15（2026-10-04）：主頁 Header「限時（月度）徽章」大 chip —— 名上面一行
   ⚠️ 全部喺檔尾 append，上面任何既有 rule（含 .header-*／.app-header／.header-avatar
      148px／84px 嗰幾條）一字未改；只加新 class，前綴一律 header-badge-。

   做法：components.js 嘅 UI.header 讀 /api/auth/me 嘅 earnedBadges，抽出當前持有嘅
        月榜 code（monthavg／monthvol／monthsub）→ 喺 .header-name-row 之上砌
        <div class="header-badge-monthrow"><span class="header-badge-chip">…。
        · 每個 chip ＝ 30px 徽章圖 ＋ 中文徽章名（唔靠圖自己講，因為 owner 要求「寫明係咩章」）；
          冇月榜徽章 → 成行都唔會 append，所以 header 高度對冇章嘅人完全唔變。
        · 金色系全部用現有 token（--gold／--gold-soft）＋ 本檔沿用的 rgba(255,184,0,·)
          發光寫法（同 .capsule-streak:527／.avatar-ring-gold:4097 一致）；
          文字色 #8A5A00 亦係本檔 .tag-gold:533／.own-cell.shelf:671 一值沿用嘅金底深字，
          喺 --gold-soft 底上對比約 5.5:1，font-weight:900 一定睇得清。
        · 尺寸：chip 高 34px（≤980px 收成 30px）＋ 圖 30px（≤980px 28px），符合「圖 28–32px」；
          一行排得落就一個 chip 一個 pill，排唔落就 flex-wrap 落第二行，永遠唔會橫向滾動。
   ============================================================================ */

/* ---- ① 名上面嗰行容器：靠 flex-wrap 自動換行，唔會撐爆 header-info ---- */
.header-badge-monthrow{
  display:flex;flex-wrap:wrap;align-items:center;gap:6px;
  margin:0 0 7px;min-width:0;max-width:100%;
}

/* ---- ② chip：金色膠囊（圖 ＋ 徽章名），固定高度令 header 唔會爆高 ---- */
.header-badge-chip{
  display:inline-flex;align-items:center;gap:6px;
  height:34px;max-height:34px;box-sizing:border-box;
  padding:0 11px 0 4px;flex:none;max-width:100%;
  border:1px solid var(--gold);border-radius:var(--radius-pill);
  background:var(--gold-soft);
  box-shadow:0 1px 2px rgba(15,23,42,.06), 0 0 0 3px rgba(255,184,0,.16);
  color:#8A5A00;font-weight:900;white-space:nowrap;
}

/* ---- ③ chip 內嘅徽章圖（30px，比名旁 20px 小圖示明顯大） ---- */
.header-badge-chip-img{width:30px;height:30px;flex:none;display:block;}

/* ---- ④ chip 內文字：全名（wide）／短名（≤560px 先出，見下） ---- */
.header-badge-chip-name{
  font-size:13px;font-weight:900;line-height:1.1;letter-spacing:.2px;
  overflow:hidden;text-overflow:ellipsis;
}
.header-badge-chip-short{display:none;}

/* ---- ⑤ ≤980px：窄位改「圖 ＋ 短名」＋ 收細一級 ----
   點解係 980px：實測（真瀏覽器）三個闊度嘅 .header-info 可用闊度係
     1280px → 351px、768px → 219px、360px → 292px（≤640px 時 info 會自己換行食足一行）。
   即係話 768px 平板嘅中間欄比 360px 手機仲窄！3 個 5 字全名 chip 要 382px，
   喺 219px 會疊成 3 行（實測 rowH 114px、header 高 215.4）。
   換成 4／3 字短名（每個 95.8／83.6px）之後，768px 只需 2 行（rowH 65px）→
   header 高度回落去 176px（＝冇 chips 嗰陣嘅高度，即係完全冇撐高）；
   360px 更加 3 個一行放得落（273px ≤ 292px，rowH 30px）。
   正式全名照樣喺 chip 嘅 title／aria-label（讀屏同長按可見），資訊冇少。 */
@media (max-width:980px){
  .header-badge-monthrow{gap:5px;margin-bottom:6px;}
  .header-badge-chip{height:30px;max-height:30px;gap:5px;padding:0 9px 0 3px;}
  .header-badge-chip-img{width:28px;height:28px;}
  .header-badge-chip-name{font-size:12px;}
  .header-badge-chip-full{display:none;}
  .header-badge-chip-short{display:inline;}
}

/* ============================================================================
   v6.11（2026-10-04）：學生 nav 加返「登出」（第 6 格）嘅窄螢幕配套
   —— 只喺檔尾 append，上面任何既有 rule 一字未改。

   背景：個人學生（personal）nav 由 5 格（主頁／做卷／朋友／團隊／我的檔案）加返
   第 6 格「登出」。≤600px 本來已經係 icon-only（只有登出保留文字）；6 格喺 360px
   完全放得落（實測總闊約 313px < 360px、0 溢出、0 橫向滾動）。

   ⚠️ 601–820px 文字版：6 格（主頁 89 ＋做卷 89 ＋朋友 89 ＋團隊 89 ＋我的檔案 116
      ＋登出 89 ＋ gap 8×5 ＋左右 padding 24）≈ 613px → 601px 溢出、最窄到約 640px
      才剛剛放得落。所以喺呢個 range 提早將「6 格」nav 收成 icon-only（登出照舊保留文字）。
   只針對 nav-dense（＝只得 personal 學生有 6 格；由 app.js renderNav 落 class）：
   parent（3 格）／owner（2 格）／inst_admin（3 格）／inst_student（5 格）不受影響，
   601–1023px 照舊顯示文字，外觀完全一樣。

   高度／觸控：44px 一個都冇縮（icon-only 格維持 min-width／min-height 44px）。
   ============================================================================ */
@media (max-width:820px){
  #app-nav.nav-dense .nav-item > span{display:none;}
  /* icon-only 嘅唯一例外：登出保留「登出」兩個字 */
  #app-nav.nav-dense .nav-item-logout > span{display:inline;}
}

/* 最窄（≤400px，例如 320px 一類）：6 格連登出文字約需 336px，320px 會差約 16px。
   nav 係 overflow-x:auto（內部橫捲、唔會令整頁橫向滾動），但登出會俾切咗。
   所以再收一級：gap 4→2、每格左右 padding 各收 2px、nav 左右留白 12→8px。
   只套用喺 nav-dense（6 格學生 nav）；44px 高度／觸控照舊唔郁。 */
@media (max-width:400px){
  #app-nav.nav-dense{
    gap:2px;
    padding-left:calc(8px + env(safe-area-inset-left,0px));
    padding-right:calc(8px + env(safe-area-inset-right,0px));
  }
  #app-nav.nav-dense .nav-item{padding:9px 8px;}
}

/* ===========================================================================
   數學科作答「草稿紙」（僅 append；class 契約：.draft-btn／.draft-mask／.draft-sheet／
   .draft-bar／.draft-title／.draft-tool／.draft-close／.draft-canvas-wrap／.draft-canvas）
   ---------------------------------------------------------------------------
   由 pages/exam.js openDraft() 砌出嚟，overlay 掛 document.body（唔在 #app 之內）。
   · .draft-btn：題目卡 .q-head 尾部一粒掣，跟 .q-flag 同一套（flex:none、熱區 ≥44×44、
     預設透明底）；只有「數學」卷先會有呢粒掣。
   · .draft-mask：全螢幕白紙（z-index 320，高過 .loading-mask 300），由邊到邊都係白；
     高度 100vh，支援 100dvh 嘅瀏覽器用 dvh（iOS 網址欄收縮時唔會被切）。
   · .draft-bar：浮喺白紙上面嘅圓角 card（同 .card 一套代幣：圓角＋淡邊＋陰影），
     白紙本身鋪滿整個畫面，所以「圓角／card 感」由工具列承擔。
   · 觸控：mask／wrap／canvas 一律 touch-action:none（畫線唔會拉動頁面），
     overscroll-behavior:contain（唔會連鎖捲動背景），並關掉 iOS 長按選單／高亮。
   · 工程取捨：工具列用 flex 而唔橫捲，窄到 320px 時 .draft-title 會縮到 ellipsis，
     但 4 粒掣（3 工具＋關閉）每個都維持 ≥44×44，唔會為咗塞版面而縮熱區。
   =========================================================================== */

/* 題目卡尾部「草稿紙」掣：完全對齊 .q-flag 的量度（同一個 header 有兩粒掣都唔會走樣） */
.draft-btn{
  flex:none;
  align-self:center;
  display:inline-flex;align-items:center;justify-content:center;gap:4px;
  min-width:44px;min-height:44px;         /* 熱區 ≥44×44 */
  padding:6px 10px;
  margin:0;
  font-family:inherit;
  font-size:var(--fs-sm,13.5px);
  font-weight:800;
  line-height:1;
  color:#94A3B8;
  background:transparent;
  border:1px solid transparent;
  border-radius:12px;
  cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  transition:background .15s ease, color .15s ease, border-color .15s ease;
}
.draft-btn:hover{
  background:var(--surface,#F1F5F9);
  border-color:var(--line,#E2E8F0);
  color:var(--ink-soft,#475569);
}
.draft-btn:focus-visible{outline:2px solid var(--brand,#2A5CE8);outline-offset:2px;}
.draft-btn:active{transform:translateY(1px);}

.draft-mask{
  position:fixed;
  top:0;left:0;right:0;
  z-index:320;                            /* > .loading-mask 300 */
  display:flex;
  box-sizing:border-box;
  height:100vh;                           /* fallback（唔支援 dvh 嘅瀏覽器） */
  padding:0;
  background:var(--card,#FFFFFF);         /* 全螢幕白色「紙」：由邊到邊都係白 */
  overscroll-behavior:contain;
  touch-action:none;
  -webkit-user-select:none;user-select:none;
  -webkit-touch-callout:none;
  -webkit-tap-highlight-color:transparent;
}
@supports (height:100dvh){
  .draft-mask{height:100dvh;}
}

/* 紙本身鋪滿整個畫面（唔加邊框／圓角，先做到「全螢幕白紙」）；
   「圓角＋card 感」由上面嗰條浮起嘅工具列卡（.draft-bar）負責。 */
.draft-sheet{
  flex:1 1 auto;
  min-width:0;
  display:flex;
  flex-direction:column;
  background:var(--card,#FFFFFF);
  overflow:hidden;
}

/* 頂部細工具列：浮喺白紙上面嘅圓角卡（跟 .card 同一套代幣） */
.draft-bar{
  flex:none;
  display:flex;
  align-items:center;
  gap:6px;
  margin:calc(10px + env(safe-area-inset-top,0px)) calc(10px + env(safe-area-inset-right,0px))
         0 calc(10px + env(safe-area-inset-left,0px));
  padding:8px 10px;
  background:var(--card,#FFFFFF);
  border:1px solid var(--card-border,rgba(226,232,240,.9));
  border-radius:18px;
  box-shadow:var(--card-shadow,0 1px 2px rgba(15,23,42,.04),0 6px 16px rgba(15,23,42,.05));
  box-sizing:border-box;
}
.draft-title{
  flex:1 1 auto;
  min-width:0;
  margin-right:2px;
  font-size:14px;
  font-weight:800;
  color:var(--ink,#0F172A);
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}

/* 工具掣（清除／撤銷／重做）：熱區 ≥44×44，唔用 transform 撐大 */
.draft-tool{
  flex:none;
  display:inline-flex;align-items:center;justify-content:center;
  min-width:44px;min-height:44px;
  padding:6px 12px;
  margin:0;
  font-family:inherit;
  font-size:14px;
  font-weight:800;
  line-height:1;
  color:var(--ink-soft,#475569);
  background:var(--surface,#F1F5F9);
  border:1px solid var(--line,#E2E8F0);
  border-radius:12px;
  cursor:pointer;
  white-space:nowrap;
  -webkit-tap-highlight-color:transparent;
  transition:background .15s ease, color .15s ease, border-color .15s ease, opacity .15s ease;
}
.draft-tool:hover:not([disabled]){
  background:#E7EDF7;
  border-color:#CBD5E1;
  color:var(--ink,#0F172A);
}
.draft-tool:focus-visible{outline:2px solid var(--brand,#2A5CE8);outline-offset:2px;}
.draft-tool[disabled]{opacity:.42;cursor:default;}

/* 關閉（×）：獨立較顯眼，熱區 ≥44×44 */
.draft-close{
  flex:none;
  display:inline-flex;align-items:center;justify-content:center;
  min-width:44px;min-height:44px;
  padding:0;
  margin:0;
  font-family:inherit;
  font-size:24px;
  font-weight:800;
  line-height:1;
  color:var(--ink-soft,#475569);
  background:var(--surface,#F1F5F9);
  border:1px solid var(--line,#E2E8F0);
  border-radius:12px;
  cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  transition:background .15s ease, color .15s ease, border-color .15s ease;
}
.draft-close:hover{
  background:#FFE4E9;
  border-color:var(--coral,#F43F5E);
  color:var(--coral,#F43F5E);
}
.draft-close:focus-visible{outline:2px solid var(--brand,#2A5CE8);outline-offset:2px;}

/* 畫布區：白底、填滿剩餘高度；touch-action:none 係畫線唔拉頁嘅關鍵。
   margin-bottom 用 safe-area-inset-bottom：iPhone 底部有 home indicator 時，
   畫布唔會貼到最底，避免喺系統手勢區畫線會拉出主畫面（env() 唔支援／非 iOS 時 = 0，無影響）。 */
.draft-canvas-wrap{
  position:relative;
  flex:1 1 auto;
  min-height:0;
  margin-bottom:env(safe-area-inset-bottom,0px);
  background:#FFFFFF;
  overflow:hidden;
  overscroll-behavior:contain;
  touch-action:none;
}
.draft-canvas{
  position:absolute;
  top:0;left:0;
  display:block;
  width:100%;
  height:100%;
  background:#FFFFFF;
  touch-action:none;
  cursor:crosshair;
  -webkit-user-select:none;user-select:none;
  -webkit-touch-callout:none;
  -webkit-tap-highlight-color:transparent;
}

/* 極窄（≤360px）：工具列卡左右留白收窄少許，4 粒掣嘅 44px 熱區不動 */
@media (max-width:360px){
  .draft-bar{
    gap:4px;
    padding:6px 8px;
    margin:calc(6px + env(safe-area-inset-top,0px)) calc(6px + env(safe-area-inset-right,0px))
           0 calc(6px + env(safe-area-inset-left,0px));
  }
  .draft-tool{padding:6px 9px;}
}

/* 較闊螢幕（≥900px）：紙照樣鋪滿整個畫面（維持「全螢幕白色」），
   但工具列卡居中收窄，唔會拉成一條橫跨 1400px 嘅長 bar。 */
@media (min-width:900px){
  .draft-bar{width:min(1100px,calc(100% - 24px));margin:12px auto 0;}
}

