/* =========================================================
   Bonder design tokens，依 docs/design.md 與設計稿取樣定稿
   色值來源：設計師 Figma 截圖（docs/design/figma-screenshots）
   加上設計稿 p24 色票、p25 文字樣式
   ---------------------------------------------------------
   RWD 斷點約定（docs/design.md「RWD 設計理由與跨檔機制」D2）：
     ≥1440        桌機基準，零視覺變更（回歸保險線）
     901–1439     輕度調整（topbar 換行、網格 auto-fill 降欄、洞察單欄 <1024）
     ≤900         殼層轉換（側欄→頂部品牌條、雙欄收單欄）
     ≤600         手機細節（stepper/padding/對話框內部欄寬）
     無條件桶      桌機不觸發的安全修正（flex-wrap、min()、overflow-x），不進 media
   custom property 不能用於 media 條件；斷點值以 docs/design.md 為規格權威，本註解為實作對照（不一致時以 design.md 為準）。
   ========================================================= */
:root {
  /* 品牌色 */
  --color-primary: #04B2ED;        /* 主色：亮青藍（主按鈕、頭像、連結） */
  --color-primary-dark: #00596C;   /* 深青藍：頁面大標題、側欄深色裝飾 */
  --color-accent: #FFB321;         /* 琥珀：選中 Tab 底線、報名中狀態、裝飾 */

  /* 側欄品牌漸層：公開／參加方為藍系（取樣自 figma-screenshots，線性雙 stop）；主辦方為青綠系（取樣自 p45/p58/p62） */
  --gradient-rail-public: linear-gradient(180deg, #05BAF2 0%, #0295DB 100%);
  --gradient-rail-host: linear-gradient(175deg, #05C3F7 0%, #04C8D9 48%, #02CFA8 100%);
  /* 側欄深色裝飾（四分之一環等）：公開為深藍、主辦方為深青 */
  --rail-decor-dark: #1E3F7D;

  /* 輔助藍系（p24 色票） */
  --color-blue-900: #1E3F7D;
  --color-blue-600: #135DAB;
  --color-blue-300: #63A8EF;

  /* 狀態色（figma-screenshots 個人_活動總覽 取樣；p62 的截止/結束兩色相反，以設計師匯出為準） */
  --color-status-open: #FFB321;    /* 活動報名中 */
  --color-status-closing: #9382FF; /* 報名即將截止 */
  --color-status-closed: #FF8284;  /* 報名已截止 */
  --color-status-upcoming: #939393;/* 尚未開始（設計稿未出現，暫用次要灰） */
  --color-danger: #FF8284;
  /* 錯誤「文字」專用的深紅。設計稿的 --color-danger 是徽章與框線用的淺珊瑚，
     拿它當白底上的內文色時對比只有 2.39:1，遠低於 WCAG AA 對一般文字要求的 4.5:1，
     而錯誤訊息偏偏是最需要讀得清楚的一種文字（field__error 只有 12px）。這一支是 5.62:1。
     徽章、框線與實心紅底鈕維持原本的 --color-danger，不動設計稿定下的色彩。 */
  --color-danger-text: #C62828;

  /* 文字色階（p25） */
  --color-text-title: #1E3F7D;     /* 頁面大標題（公開／參加方為深藍；主辦方頁另為深青 #00596C） */
  --color-text-title-host: #00596C;
  --color-text-strong: #202020;    /* 中小標 */
  --color-text-body: #606060;      /* 內文 */
  --color-text-muted: #939393;     /* 備選選單 */
  --color-text-disabled: #E0E0E0;  /* 欄位上鎖 */

  /* 底色與框線 */
  --color-surface: #FFFFFF;
  --color-surface-alt: #F2F2F2;    /* 內容面板、搜尋框底 */
  --color-border: #E0E0E0;
  --color-border-strong: #939393;

  /* 圓角（卡片 8–16、按鈕全圓角） */
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 16px;
  --radius-rail: 24px;
  --radius-pill: 9999px;

  /* 間距（8px 系統） */
  --space-1: 8px;
  --space-2: 16px;
  --space-3: 24px;
  --space-4: 32px;
  --space-5: 40px;
  --space-6: 48px;

  /* 字級 tokens：clamp 取最大值的視口門檻各為 800/711/500px，桌機恆為現值（h3 尚未有套用點） */
  --font-size-h1: clamp(24px, 5vw, 40px);
  --font-size-h2: clamp(22px, 4.5vw, 32px);
  --font-size-h3: clamp(18px, 4vw, 20px);
  /* 行動觸控目標下限：在 @media (pointer: coarse) 套用到 chip、按鈕與分頁（見下方 reset 區塊） */
  --touch-target: 44px;

  --shadow-card: 0 2px 8px rgba(0, 0, 0, .06);
  --shadow-dialog: 0 8px 32px rgba(0, 0, 0, .16);

  --font-sans: "Noto Sans TC", "Microsoft JhengHei", "PingFang TC", "Segoe UI", sans-serif;
}

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font-sans);
  color: var(--color-text-strong);
  background: var(--color-surface);
  font-size: 16px;
  line-height: 1.5;
}
img { max-width: 100%; display: block; }
/* select 的固有寬度取最長 option：30 字的活動標題會把 417px 的下拉直接推破 375 視口，
   而 select 內文（單行控制項）本就由瀏覽器以省略號截斷，壓回容器寬沒有資訊損失 */
select { max-width: 100%; }
a { color: var(--color-primary); text-decoration: none; }
button { font-family: inherit; cursor: pointer; }

/* 鍵盤焦點基線：全站原本只有兩處自訂 focus 樣式，其餘靠瀏覽器預設，
   在深色底、膠囊按鈕與 chip 上常常看不清楚。用 :focus-visible 只在鍵盤操作時出現
   （滑鼠點選不會長出外框），並以 :where() 壓低特異度，個別元件仍可自行覆寫。
   認證頁輸入框刻意維持既有的底線變色設計，那一處的 :focus 特異度較高、不受本規則影響。 */
:where(a, button, summary, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: 2px;
}

/* 觸控目標下限：只作用在**指標粗略**的裝置（手指），桌機滑鼠不受影響、版面不變。
   以 min-height 加置中實現，不動寬度，避免把並排的 chip 撐開換行。 */
@media (pointer: coarse) {
  .chip, .btn, .btn--outline, .action-btn, .modal__btn, .phase-reg__btn, .copy-btn, .page-tabs__item {
    min-height: var(--touch-target);
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* 純圖示連結（活動頁的 Facebook 與 Instagram，圖示 26×26）：沒有文字可以瞄準，
     是最需要放大熱區的一種。連寬度一起給下限——上面那批是有文字的按鈕，只給高度是為了
     不把並排的 chip 撐開換行，圖示連結沒有這個顧慮。 */
  .detail-brief__social-links a {
    min-width: var(--touch-target);
    min-height: var(--touch-target);
    align-items: center;
    justify-content: center;
  }
  /* 密碼欄的顯示切換鈕只有 22×27，而在手機上輸入密碼正是最想按它的時候。它是絕對定位、
     貼齊輸入框底線的圖示，直接給 min-height 會把圖示往上推離原位；改用外擴的 ::after
     把熱區推到 46×51，圖示一動也不動。 */
  .afield__eye::after { content: ""; position: absolute; inset: -12px; }
  /* 勾選與單選那一列：原生控制項只有 13×13，靠包住它的 label 才點得到，而短標籤的 label
     也只有 21px 高（報名表的「我已閱讀並同意」正是這樣，還是送出前的必經一步）。整條
     label 撐到觸控下限，手指落在文字附近就有效。長標籤本來就會折行超過 44px，不受影響。 */
  .afield-remember, .field__choice { min-height: var(--touch-target); }
  /* 這三類原本記在 progress.md 的「套用範圍之外」，後來決定一起納入：返回連結（21px）是
     每一頁的離開動線、帳號選單項（34px）是選單裡的全部動作、語言切換鈕（29px）是換語言的
     唯一入口——三者都是常按的東西，不是偶爾按。返回連結用 inline-flex 只撐高、不動寬度，
     免得整條變成一整列的點擊區、蓋住旁邊的東西。 */
  .register-back, .topbar__back {
    display: inline-flex;
    align-items: center;
    min-height: var(--touch-target);
  }
  /* 原本是 height:34px 配 line-height:32px；只放大 min-height 的話文字會黏在上緣，
     改成 flex 置中並讓 line-height 交還給 flex 對齊 */
  .account-menu__btn {
    display: flex;
    align-items: center;
    justify-content: center;
    height: auto;
    min-height: var(--touch-target);
    line-height: normal;
  }
  .culture-switcher__btn { min-height: var(--touch-target); }
}

/* 動態效果的減弱偏好（作業系統層級的「減少動態效果」）。
   判準是**位置有沒有變**，不是「有沒有 transition」：會位移、旋轉、縮放的效果才關掉，
   顏色、透明度、filter、陰影的過渡一律保留——那些不會引起前庭不適，關掉反而讓狀態變化
   顯得突兀。因此 .btn-primary 的 filter、.afield input 的底線變色、.culture-switcher 的
   opacity、.phase-steps__btn 的背景色都刻意不列在這裡。
   新增會動的效果時要一併加進這一份清單；對話框與兩支 keyframes 各自就近有自己的守衛
   （.modal 在對話框段、submit-busy-spin 與 skeleton-shimmer 在各自的段落）。 */
@media (prefers-reduced-motion: reduce) {
  /* 略過導覽連結：平時在畫面外，聚焦時滑入——關掉之後改為直接出現，功能不受影響 */
  .skip-link { transition: none; }
  /* 展開收合的三角與箭頭：旋轉 */
  .register-heading--collapsible::before,
  .faq-item__q::after { transition: none; }
  /* 開關的圓鈕：左右滑動 */
  .scoring-toggle__knob { transition: none; }
}

/* ---------- 全站骨架：品牌側欄、主內容 ---------- */
/* 略過導覽連結：平時移出畫面，獲得鍵盤焦點才滑入左上角。
   不用 display:none——那會讓連結連焦點都拿不到，等於沒做。
   主內容區掛 tabindex="-1"，跳過去之後焦點才真的落在那裡（否則只有捲動、Tab 仍從頭來） */
.skip-link {
  position: absolute;
  left: var(--space-3);
  top: -60px;
  z-index: 100;
  padding: 10px 16px;
  border-radius: var(--radius-sm);
  background: var(--color-primary);
  color: #FFFFFF;
  font-weight: 700;
  text-decoration: none;
  transition: top .15s ease-in-out;
}
.skip-link:focus { top: var(--space-3); }
#main-content:focus { outline: none; }

.app-shell {
  display: flex;
  min-height: 100vh;
  gap: var(--space-5);
  padding: var(--space-6) var(--space-5);
}

/* 品牌漸層側欄（設計稿 p62：圓角面板、logo、幾何裝飾） */
.brand-rail {
  position: sticky;
  top: var(--space-6);
  align-self: flex-start;
  flex: 0 0 315px;
  border-radius: var(--radius-rail);
  background: var(--gradient-rail-public);
  overflow: hidden;
  height: calc(100vh - 96px);
}
.brand-rail--host {
  background: var(--gradient-rail-host);
  --rail-decor-dark: #00596C;
}
/* admin 是內部工具，採深藍單色系（figma 風格延伸，無截圖基準） */
.brand-rail--admin {
  background: linear-gradient(160deg, #1E3F7D 0%, #135DAB 100%);
  --rail-decor-dark: #0F2A55;
}
.brand-rail__logo {
  position: absolute;
  top: 56px;
  left: 68px;
  width: 168px;
  height: auto;
}
.brand-rail__decor {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.app-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  /* 右下角固定浮動的語系切換鈕的退路：捲到底時鈕落在這段空白上，不壓最後一列內容。
     放在內容欄而不是 body——body 級的退路會把 min-height:100vh 的版式撐出視口，
     讓內容不足一屏的頁面平白多一條 48px 的可捲白條（auth 分割版式另由 .auth-side 的下內距負責） */
  padding-bottom: 48px;
}

/* ---------- 頂欄 ---------- */
.topbar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 20px 0 0;
}
.topbar__title {
  margin: 0;
  font-size: var(--font-size-h1); /* RWD P1：clamp，≥800px 恆 40px */
  font-weight: 700;
  color: var(--color-text-title);
  white-space: nowrap;
}
/* EN 標題比繁中長一截（如 Find activities you're interested in），>1024 的桌機帶也可能塞爆
   nowrap 的一列 topbar 而撐出整頁橫向捲軸；僅對英文放行依詞界折行，繁中不受影響 */
html:lang(en) .topbar__title { white-space: normal; }
.topbar__back {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--color-text-body);
  font-size: 14px;
}
.topbar__search {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  height: 48px;
  padding: 0 var(--space-2);
  margin-left: var(--space-2);
  background: var(--color-surface-alt);
  border-radius: var(--radius-md);
}
.topbar__search svg { flex: 0 0 auto; color: var(--color-text-muted); }
.topbar__search input {
  flex: 1 1 auto;
  /* 撐滿外框的 48px：外框是 form 不是 label，點在輸入框以外的地方不會聚焦，
     於是那個看起來 343×48 的搜尋框，實際可點的只有中間 281×26 那一條——
     上下各 11 像素點下去毫無反應。手機上這是找活動的主要入口，最不該漏接。
     輸入框的文字本來就垂直置中，撐高之後外觀不變，變的只有命中範圍。 */
  align-self: stretch;
  border: 0;
  background: transparent;
  font: inherit;
  color: var(--color-text-strong);
  outline: none;
}
.topbar__search input::placeholder { color: var(--color-text-muted); }

/* 送出鎖（submit-lock.js）：送出後的按鈕降不透明度、改游標並附轉圈，慢速網路下看得出「已在處理」 */
button[type="submit"][aria-busy="true"] { opacity: .6; cursor: progress; }
button[type="submit"][aria-busy="true"]::after {
  content: "";
  display: inline-block;
  box-sizing: border-box;
  width: .85em;
  height: .85em;
  margin-left: .5em;
  vertical-align: -.1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: submit-busy-spin .7s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  /* 靜止的缺口圓環仍是「處理中」的視覺標記，只是不轉 */
  button[type="submit"][aria-busy="true"]::after { animation: none; }
}
@keyframes submit-busy-spin { to { transform: rotate(360deg); } }

/* 帳號區（個人化：二次載入補上，不進 OutputCache） */
.account-area {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  white-space: nowrap;
}
/* RWD P0：長顯示名截斷（防擠爆 topbar；>8em 時桌機亦截斷，屬可接受的防禦性收斂） */
.account-area__name { font-size: 14px; color: var(--color-text-strong); max-width: 8em; overflow: hidden; text-overflow: ellipsis; }
.account-area__avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  display: grid;
  place-items: center;
}
.account-area__login {
  display: inline-flex;
  align-items: center;
  height: 40px;
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--color-primary);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
}

/* ---------- 頁內 Tab（選中態底線） ---------- */
/* RWD 決議 D4 為橫捲（docs/design.md「RWD 設計理由與跨檔機制」）：無條件套用，桌機寬度足夠不觸發捲動，
   窄幅時水平滑動而非擠壓（CJK 逐字直排即擠壓特徵） */
.page-tabs {
  display: flex;
  gap: var(--space-4);
  margin-top: var(--space-3);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* 藏實體捲軸：溢出提示交給右緣淡出遮罩與 › 鈕（英文語系的後台分頁在桌面 Windows
     會溢出，實體捲軸和遮罩提示並存時畫面出現兩條裸捲軸）；捲動能力不受影響 */
  scrollbar-width: none;
}
.page-tabs::-webkit-scrollbar { display: none; }
/* 右緣淡出：提示可橫向捲動。只在「還能往右捲」時由 JS（_Layout）掛上 --masked；
   無條件套用會在分頁剛好排滿容器時把末項尾字誤淡出成看似被裁切（admin 導覽 390px 即此例） */
.page-tabs--masked {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 20px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 20px), transparent);
}
.page-tabs__item {
  flex: 0 0 auto;
  white-space: nowrap;
  font-size: 20px;
  font-weight: 700;
  color: var(--color-text-muted);
  padding-bottom: 6px;
  border-bottom: 4px solid transparent;
}
.page-tabs__item--active {
  color: var(--color-text-strong);
  border-bottom-color: var(--color-accent);
}
/* 可橫向捲動的分頁導覽列右緣提示：分頁放不下且未捲到底時，JS 於 .page-tabs-scroll 加 --scrollable 顯示 › 鈕，
   底色白（頁面 body 底）漸層加上箭頭比單純淡出遮罩更明顯；點選向右捲一段，也可直接左滑 */
.page-tabs-scroll { position: relative; }
.page-tabs-scroll__more {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 52px;
  display: none;
  align-items: center;
  justify-content: flex-end;
  padding-right: 2px;
  border: 0;
  background: linear-gradient(to right, rgba(255, 255, 255, 0), #fff 55%);
  color: var(--color-text-strong);
  cursor: pointer;
}
.page-tabs-scroll--scrollable .page-tabs-scroll__more { display: flex; }

/* ---------- 內容面板 ---------- */
.content-panel {
  position: relative;
  margin-top: var(--space-2);
  padding: var(--space-4);
  background: var(--color-surface-alt);
  border-radius: var(--radius-lg);
  flex: 1 1 auto;
}
.content-panel__illustration {
  position: absolute;
  right: 0;
  bottom: 8px;
  width: 283px;
  pointer-events: none;
  opacity: .45; /* 淡化為背景浮水印：被卡片遮住時只露一角也讀作裝飾、不像雜訊 */
}
/* 純裝飾圖裁進圓角面板內，不在右緣硬切出一截（僅作用於含此圖的清單面板，不影響編輯器面板） */
.content-panel:has(.content-panel__illustration) { overflow: hidden; }

/* ---------- 篩選 chip ---------- */
.filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 12px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  border: 1px solid transparent;
  background: var(--color-surface);
  /* chip 語義是單行小標籤：在 flex 標題列（如設定頁卡片標題旁的「✎ 編輯」）被長標題
     壓縮時不得折成逐字直排 */
  flex-shrink: 0;
  white-space: nowrap;
}
.chip--solid {
  background: var(--color-text-body);
  color: #fff;
}
.chip--open { border-color: var(--color-status-open); color: var(--color-status-open); }
.chip--closing { border-color: var(--color-status-closing); color: var(--color-status-closing); }
.chip--closed { border-color: var(--color-status-closed); color: var(--color-status-closed); }
a.chip { text-decoration: none; cursor: pointer; }
/* 按鈕型 chip（設定頁「套用」、審查的「加入註記」等）：標籤型 chip 的透明邊框讓它們
   看起來像純文字標籤，讀不出可以按；補可見邊框與 hover 變化，不影響 span/a 的標籤用法 */
button.chip { border-color: var(--color-text-disabled); cursor: pointer; }
/* 審查作業的主要動作 chip（退回補件）：測試回饋指出審查頁最重要的動作長得像標籤，補填色樣式突顯 */
button.chip--primary { background: var(--color-primary); border-color: var(--color-primary); color: #fff; }
/* hover 一律包在 (hover: hover) 裡——理由見檔案後段「觸控裝置的 hover 殘留」那一段 */
@media (hover: hover) {
  button.chip:hover { border-color: var(--color-primary); color: var(--color-primary); }
  button.chip--primary:hover { border-color: var(--color-primary); color: #fff; opacity: .88; }
}
/* 篩選啟用態：以 chip 自身狀態色打淡當背景（figma 未給啟用態，取最小可辨樣式） */
.chip--active {
  background: color-mix(in srgb, currentColor 12%, #fff);
  font-weight: 600;
}

/* ---------- 頭像下拉選單（figma：個人_活動總覽_頭像功能） ---------- */
.account-menu { position: relative; }
.account-menu > summary { list-style: none; cursor: pointer; }
.account-menu > summary::-webkit-details-marker { display: none; }
.account-menu__card {
  position: absolute;
  top: calc(100% + 12px);
  right: 0;
  width: 200px;
  padding: var(--space-3) var(--space-2) var(--space-2);
  background: var(--color-surface);
  border-top: 4px solid var(--color-primary);
  border-radius: var(--radius-sm);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.12);
  z-index: 20;
  text-align: center;
}
.account-menu__name { font-size: 16px; font-weight: 700; color: var(--color-text-strong); }
.account-menu__email { font-size: 13px; color: var(--color-text-body); margin-top: 4px; }
.account-menu__source { font-size: 12px; color: var(--color-text-muted); margin: 4px 0 var(--space-2); }
/* 視角狀態列（僅雙視角帳號渲染）：頁面的身分線索原本只有配色與標題，這行給明確的文字 */
.account-menu__view { font-size: 12px; font-weight: 700; color: var(--color-primary); margin: 0 0 var(--space-2); }
.account-menu__btn {
  display: block;
  width: 100%;
  height: 34px;
  line-height: 32px;
  margin-top: 8px;
  border: 1px solid var(--color-border, #E0E0E0);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font-size: 14px;
  color: var(--color-text-strong);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}
.account-menu__btn--primary {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

/* ---------- 通用簡潔卡片（auth 訊息頁、admin 登入、後台與報名表單等多頁共用；figma tokens 延伸，無截圖基準） ---------- */
.auth-card {
  max-width: 420px;
  margin: var(--space-6) auto;
  padding: var(--space-4, 32px) var(--space-3);
  background: var(--color-surface);
  border-radius: var(--radius-sm);
}
.auth-card__title { font-size: 24px; color: var(--color-text-title); margin-bottom: var(--space-3); }
.auth-card__notice { margin-bottom: var(--space-2); font-size: 14px; color: var(--color-text-body); }
/* 結果訊息做成色塊而不是又一行文字。原本兩者只換文字顏色，於是「權限已更新」「已儲存並發布」
   這類回報混在同一段說明文字裡，做完一件事之後畫面幾乎沒有變化，很容易被當成沒反應而重按一次。
   底色與左側色條沿用 readiness-status 那一組（成功綠、警示橘紅），全站的結果回報因此看起來是同一件事。 */
.auth-card__notice--ok,
.auth-card__notice--error,
.auth-card__notice--info {
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  border-left: 3px solid currentColor;
}
.auth-card__notice--ok { color: #2E7D32; background: #E8F5E9; }
.auth-card__notice--error { color: var(--color-danger-text); background: #FDECEA; }
/* 中性的狀態色塊：說明「現在處於什麼狀態、因此哪些動作不見了」，不是成功也不是錯誤。
   報名截止後的確認頁是代表——同一頁的動作錯誤是紅色塊，而讓整頁動不了的截止狀態
   原本只是一行灰字，輕重剛好顛倒。底色取白而不是灰：這則訊息長在 .content-panel
   裡面，而面板本身就是 --color-surface-alt，灰底疊灰底只會剩下一條左側色條。
   外加細框讓它在白底頁面上同樣讀得出邊界（--ok 與 --error 靠色調就分得開，中性色沒有）。 */
.auth-card__notice--info {
  color: var(--color-text-strong);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-border-strong);
}
/* 後台唯讀橫幅（_BackendTabs）：灰底條狀，讓「只能檢視」在進頁當下就看得出來 */
.backend-readonly-notice { background: var(--color-surface-alt); border-radius: var(--radius-md); padding: 8px 12px; }
.auth-card__links { margin-top: var(--space-3); font-size: 14px; color: var(--color-text-body); }
.auth-card__links a { color: var(--color-primary); }
/* 錯誤頁的追蹤編號：與前面的標籤留一個字距。繁中的「Request ID：」用全形冒號、後面自帶空隙，
   英文的「Request ID:」是半形，緊接編號會黏成一團。編號本身含連字號，瀏覽器會在連字號處
   換行，375px 下不會溢出，因此不另加 word-break。 */
.request-id { margin-left: 4px; }

.field { margin-bottom: var(--space-2); }
.field label { display: block; font-size: 14px; color: var(--color-text-strong); margin-bottom: 6px; }
.field input {
  width: 100%;
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--color-text-disabled);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font-size: 14px;
}
.field__error { display: block; margin-top: 4px; font-size: 12px; color: var(--color-danger-text); }
/* 動態表單的行內錯誤容器恆存在（前端驗證只換文字），沒有訊息時不占版面，錯誤出現時才推開下一欄，
   位移只有一行字高；:empty 的節點仍可被 aria-describedby 取用，所以不影響螢幕閱讀器。 */
.field__error:empty { display: none; }
/* 錯誤狀態不只靠紅色：紅框之外一定同時有 .field__error 的文字 */
.field--invalid input:not([type="checkbox"]):not([type="radio"]),
.field--invalid textarea,
.field--invalid select { border-color: var(--color-danger); }
.field--invalid .field__choices { padding-left: 8px; border-left: 2px solid var(--color-danger); }
/* 伺服器端驗證退回時 ASP.NET 驗證管線在欄位本身加的 class：跟 .field--invalid 同一套
   紅框語彙，讓錯誤欄不必逐欄比對下方訊息就能一眼認出；auth 版式（底線欄）跟隨
   .afield__error 的深紅，focus 時仍回主色表示「正在修正」 */
input.input-validation-error, select.input-validation-error, textarea.input-validation-error { border-color: var(--color-danger); }
.afield input.input-validation-error { border-bottom-color: #E4586A; }
/* RWD P0：原生檔案控制項選檔後寬度隨檔名增長，防撐破容器（不設 width:100%；.field 內者已有滿版規則） */
input[type="file"] { max-width: 100%; }
/* .field 內的檔案控制項：原生 file 控制項的按鈕/檔名在 38px 盒內採基線對齊、下方留一截白，看起來沒對齊。
   flex、padding 對其 shadow 內容無效，改直接為 ::file-selector-button 設高度，並加上上下對稱 margin：
   盒內容高 36px（38-2border），按鈕 28 + 上下各 4 = 36，剛好垂直置中；順帶把按鈕樣式統一為淺灰膠囊鈕 */
.field input[type="file"] { height: 38px; padding: 0 12px; line-height: normal; }
.field input[type="file"]::file-selector-button {
  height: 28px;
  margin: 4px 12px 4px 0;
  padding: 0 14px;
  border: 1px solid var(--color-text-disabled);
  border-radius: var(--radius-sm);
  background: var(--color-surface-alt);
  color: var(--color-text-strong);
  font-size: 14px;
  cursor: pointer;
}
.field input[type="file"]::file-selector-button:hover { filter: brightness(0.97); }
/* flex 動態表單的單選/多選（_FlexFields；參加者填表與後台預覽共用），
   radio/checkbox 不吃 .field input 的滿版規則 */
.field__label { display: block; font-size: 14px; color: var(--color-text-strong); margin-bottom: 6px; }
/* 必填記號「＊」（學生報名表、建立活動頁、補件期限欄共用）：只染星號，欄位名稱維持原色。
   用深紅文字色而非 --color-danger——珊瑚紅是徽章與框線用色，星號字形小，白底上會糊掉 */
.field__required-mark { color: var(--color-danger-text); }
.field__choices { display: flex; flex-wrap: wrap; gap: 8px 24px; }
.field__choice { display: inline-flex; align-items: center; gap: 8px; margin-bottom: 0; }
.field .field__choice input { width: auto; height: auto; }
/* .field 內的 checkbox/radio 不吃 .field input 的滿版規則（否則勾選框會被撐成整行、置中，例如報名表格建構器的「必填」） */
.field input[type="checkbox"], .field input[type="radio"] { width: auto; height: auto; }
/* 建議清單（datalist）的輸入框是「打字＋提示」不是下拉選單：Chrome 會替 input[list] 畫下拉箭頭
   （::-webkit-calendar-picker-indicator），看起來像 <select>、誤導成只能從清單選（0818 測試回饋）。
   隱藏箭頭不影響建議清單本身（打字仍出建議）；日期欄不掛 list 屬性，日曆圖示不受影響 */
input[list]::-webkit-calendar-picker-indicator { display: none !important; }
/* 例外：學校欄是「搜尋＋下拉」——除了打字篩選，139 所完整清單也點得開，要有下拉的視覺提示。
   原生箭頭已被上一條隱藏，這裡自繪補回「│ ⌄」：箭頭前加一條外框同色（--color-border）的細分隔線，
   與純下拉的學制、年級（原生箭頭、無分隔線）做出區別（0818 測試回饋第二波）。
   科系欄不比照：建議清單要打字後才取回，沒有可點開的完整清單，維持純打字欄的樣貌。
   選擇器帶 [list] 是為了壓過 .pfield input 等同權重的 padding 設定（該規則在檔案後段） */
input[list].school-combo {
  padding-right: 40px;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.25 6 7.75l3.5-3.5' fill='none' stroke='%23202020' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"),
    linear-gradient(var(--color-border), var(--color-border));
  background-repeat: no-repeat, no-repeat;
  background-position: right 10px center, right 32px center;
  background-size: 12px 12px, 1px 20px;
}

.btn-primary {
  display: block;
  width: 100%;
  height: 40px;
  margin-top: var(--space-3);
  border: none;
  border-radius: 20px;
  background: var(--color-primary);
  color: #fff;
  font-size: 15px;
  cursor: pointer;
}

/* ---------- 報名流程（figma：參加者報名各狀態） ---------- */
.register-back {
  display: inline-block;
  margin-bottom: 8px;
  font-size: 14px;
  color: var(--color-text-muted);
  text-decoration: none;
}
/* 報名頁首列：返回總覽靠左、帳號區靠右（figma：個人報名資料） */
.register-topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.register-topbar .register-back { margin-bottom: 0; }
.register-title {
  font-size: var(--font-size-h2); /* RWD P1：clamp，≥711px 恆 32px（報名頁與活動詳細頁標題共用） */
  font-weight: 700;
  color: var(--color-text-title);
  margin-bottom: var(--space-2);
  /* 活動名稱是主辦方自由填寫的內容，與 .info-list dd、.comment__content 同一個慣例：
     沒有空白可斷的長字串（英文長名、貼進來的網址）會把整頁撐寬。實測 375px 下塞一個
     82 字元無空白的標題，文件從 360px 撐到 960px、整頁可以橫向捲 600px。
     卡片標題不受影響（卡片本身會裁切），但這個 H1 沒有任何外圍限制。 */
  overflow-wrap: anywhere;
}
.register-panel { position: relative; }
.register-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: var(--space-4, 32px);
  align-items: start;
}
.register-heading {
  font-size: 20px;
  font-weight: 700;
  color: var(--color-text-strong);
  margin-bottom: var(--space-3);
}
/* 編號與複製鈕整組不可分離：標題折行時要嘛整組留在同行、要嘛整組下行——
   在中間斷開會讓 ⧉ 孤立在行首，讀不出跟哪個編號相關（invite-hint 同款考量） */
/* 隊伍編號：隊員還沒到齊時，這組數字就是使用者當下最需要的東西（提示框寫著「尚需 N 人加入隊伍」，
   而入隊靠的正是它）。原本它是整個區塊裡最不顯眼的文字之一——次要灰、包在標題的括號裡；對照之下
   主辦方後台用 24px 粗體呈現同一組編號，而那裡其實用不到它，兩端的權重剛好顛倒。
   整段一起提到內文色與半粗，不另外拆出數字：拆的話得把「（隊伍編號：{0}）」這個資源鍵切成兩半，
   為了一點字重把三個頁面的譯文結構弄碎並不划算。 */
.register-heading__code { display: inline-block; font-size: 16px; font-weight: 600; color: var(--color-text-strong); white-space: nowrap; }
.copy-btn { border: none; background: none; cursor: pointer; font-size: 15px; color: var(--color-text-muted); }
.copy-feedback { font-size: 13px; color: var(--color-text-muted); margin-left: 4px; }
/* 邀請說明（隊長在湊人時的下一步）：與準備狀態區相鄰，語氣是提示不是警告 */
/* 不折行：說明文字撐滿剩餘寬度、複製鈕固定在句尾右側——wrap 會讓長句（尤其英文）把
   複製鈕擠到下一行開頭，孤立的 ⧉ 讀不出跟哪段文字相關 */
.invite-hint { display: flex; align-items: center; gap: 6px; margin: var(--space-2) 0; font-size: 13px; color: var(--color-text-body); }
.invite-hint > span:first-child { flex: 1 1 auto; min-width: 0; }

.readiness-status {
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  line-height: 1.6;
  margin-bottom: var(--space-3);
}
.readiness-status--ok { background: #E8F5E9; color: #2E7D32; }
.readiness-status--blocked { background: #FFF3E0; color: #E65100; }
.readiness-status ul { margin: 0; padding-left: 20px; }

.member-roster { margin-bottom: var(--space-3); }
.member-roster__heading {
  font-size: 16px;
  font-weight: 700;
  color: var(--color-text-strong);
  margin-bottom: var(--space-2);
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.member-roster__count { font-size: 13px; font-weight: 400; color: var(--color-text-muted); }
.member-roster__list { list-style: none; margin: 0; padding: 0; }
.member-roster__list li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 0;
  border-bottom: 1px solid var(--color-border);
  font-size: 14px;
}
.member-roster__list li:last-child { border-bottom: none; }
.member-roster__name { color: var(--color-text-strong); }
.member-roster__role { font-size: 12px; color: var(--color-text-muted); }
/* 「（你）」不只靠顏色：本身就是文字，配色只是加強 */
.member-roster__self { font-size: 12px; font-weight: 700; color: var(--color-primary); }

.confirm-details { margin-top: 0; }
.confirm-details[open] > summary { margin-bottom: var(--space-3); }
.register-heading--collapsible { cursor: pointer; list-style: none; }
.register-heading--collapsible::marker,
.register-heading--collapsible::-webkit-details-marker { display: none; }
.register-heading--collapsible::before { content: "▶"; font-size: 12px; margin-right: 8px; transition: transform 0.15s; display: inline-block; }
.confirm-details[open] > .register-heading--collapsible::before { transform: rotate(90deg); }

.confirm-next-step { font-size: 15px; color: var(--color-text-body); margin-top: var(--space-3); }

.register-steps {
  display: flex;
  align-items: flex-start;
  list-style: none;
  margin: 0 0 var(--space-3);
  padding: 0;
}
.register-steps__item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 180px;
}
.register-steps__item + .register-steps__item::before {
  content: "";
  position: absolute;
  top: 14px;
  right: calc(50% + 18px);
  width: calc(100% - 36px);
  height: 2px;
  background: var(--color-blue-300);
}
.register-steps__dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 2px solid var(--color-blue-600);
  color: var(--color-blue-600);
  background: var(--color-surface);
  font-size: 14px;
}
.register-steps__item--active .register-steps__dot {
  background: var(--color-blue-600);
  color: #fff;
}
.register-steps__label { font-size: 13px; color: var(--color-text-body); }
/* RWD P2（無條件桶）：階段列可達 10 項，180px×10 在任何寬度都可能超寬，
   一律橫捲而非壓縮逐字直排；階段少時不超寬、無捲軸，即桌機零變化 */
.phase-steps { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.phase-steps .register-steps__item { flex: 0 0 auto; }
/* 階段圓點是真的可以按的（切換下方顯示的階段），和報名流程那個純指示用的 stepper 共用外觀，
   所以要自己補上「可以按」的線索——只加在 .phase-steps__btn 上，不動報名流程的圓點。
   hover 給淡藍底（未選取的圓點是白底藍框，brightness 對白底沒有效果，改用實際的色塊）；
   已選取的圓點本來就是實心藍，hover 只微增亮，避免和選取態打架。 */
.phase-steps__btn { position: relative; transition: background-color .15s; }
@media (hover: hover) {
  .phase-steps__btn:hover { background: #E8F1FB; }
  .register-steps__item--active .phase-steps__btn:hover { background: var(--color-blue-600); filter: brightness(1.1); }
}
/* 觸控熱區：圓點只有 28×28，而放大圓點會把整條階段列的間距撐開。比照密碼欄眼睛鈕的做法，
   用外擴的 ::after 把熱區推到 44×44，圓點本身一動也不動。 */
@media (pointer: coarse) {
  .phase-steps__btn::after { content: ""; position: absolute; inset: -8px; }
}

/* 右欄跟著捲動。UDreamer 這類範本的個人表單有十幾欄、頁高超過兩千像素，而右欄只有一張封面
   加一行報名狀態——捲到第三欄以後右側就是一大片空白，報名狀態也早就滾出畫面。黏在視窗上之後
   那行狀態一路都看得到，空白也不再是純浪費。sticky 只在欄位夠高時才起作用，短表單維持原樣；
   窄視口下右欄已被 order:-1 移到最上方變成橫幅，那裡不需要黏住，另行取消。 */
.register-rail { position: sticky; top: var(--space-3); }
.register-rail__cover {
  width: 100%;
  border-radius: var(--radius-sm);
  display: block;
}
.register-rail__status {
  margin-top: var(--space-2);
  font-size: 15px;
  font-weight: 700;
  color: var(--color-text-strong);
}
.register-rail__status span { font-weight: 400; color: var(--color-text-body); }
/* 下一步：狀態的配套。狀態回答「我在哪」，這一行回答「所以現在該做什麼」——分成兩行、
   把標籤壓成弱色，視線才會先落在動作本身而不是「下一步」三個字。指不出動作的處境
   （截止後未送出、補件逾期）整行不渲染，理由見 _RegisterRail.cshtml。 */
.register-rail__next {
  margin-top: 6px;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px;
  font-size: 14px;
}
.register-rail__next-label { flex: 0 0 auto; color: var(--color-text-muted); }
.register-rail__next a { font-weight: 600; }
/* 指不出去處時仍是一句話而不是連結（例如把隊伍編號傳給隊友），顏色跟著內文走 */
.register-rail__next span:not(.register-rail__next-label) { color: var(--color-text-body); }

/* 報名期限：與狀態同一組資訊，但份量低一階（狀態是「我現在在哪」，期限是「還剩多久」）。
   截止之後改用警示色——那時期限不再是背景資訊，而是解釋畫面為什麼變成唯讀的那一行。 */
.register-rail__deadline {
  margin-top: 4px;
  font-size: 14px;
  color: var(--color-text-body);
}
.register-rail__deadline--ended { color: var(--color-danger-text); }

.info-list { margin: 0; }
/* 允許換行加上 dd 的最小基準寬：dt 過長（「在校證明（學生證正反面或就學證明）」）時，
   dd 剩餘寬不足一個詞就整列折到下一行，而不是把「我已閱讀並同意」逐字擠成直條 */
.info-list > div { display: flex; flex-wrap: wrap; gap: 0 8px; margin-bottom: 12px; font-size: 15px; }
/* 欄名不收縮，但擠不下時要肯折行。原本是 flex-shrink: 0：欄寬夠時效果一樣（有空間就不收縮），
   窄幅卻會把答案整個推出畫面——375px 的報名資料頁上，範本裡二十多字的同意欄名
   自己就要 285px，而它落在成員摺疊區裡、左邊已縮排 109px，於是那一列的答案被推到
   x=402（視窗只有 375）完全看不到。改成允許折行，答案就留在畫面內。
   同時要 keep-all：中文預設可以斷在任兩字之間，放行折行之後「報名時間：」會斷成「報名時」與
   「間：」（活動簡介卡的窄欄實際看到過）。keep-all 只禁止詞內斷行，遇到頓號等標點仍可換行，
   所以長欄名照樣折得下來，短欄名則整塊保留。 */
.info-list dt { color: var(--color-text-strong); flex-shrink: 1; word-break: keep-all; }
.info-list dt::after { content: "："; }
/* EN 語系標點用半形（與資源鍵層的既定方向一致；全形冒號在英文排版裡突兀） */
html:lang(en) .info-list dt::after { content: ": "; }
.info-list dd { margin: 0; color: var(--color-text-body); overflow-wrap: anywhere; flex: 1 1 10em; min-width: 0; }
/* 鎖定欄還沒填時的佔位字：比內文淡一階，一眼看得出這是「還沒填」而不是某人填了這幾個字 */
.info-list__unset { color: var(--color-text-muted); }
/* 長文列（個人簡歷/團隊介紹）：標籤與內文同行起排、換行滿版（figma 唯讀頁）；
   特異度需壓過 .info-list > div 的 flex */
.info-list > div.info-list__full { display: block; }
.info-list > div.info-list__full dt,
.info-list > div.info-list__full dd { display: inline; }
.info-list a { color: var(--color-primary); }
.info-divider { border: none; border-top: 1px solid #E0E0E0; margin: var(--space-3) 0; }

.register-actions {
  display: flex;
  flex-wrap: wrap; /* RWD P0：隊長態最多 5 顆鈕 */
  gap: var(--space-2);
  margin-top: var(--space-3);
}
/* 破壞性動作（取消報名、解散隊伍、移除隊員、退出隊伍）與往前推進的動作分家：
   收成內容寬並靠到最右，中間留出空白。五顆鈕等寬並排時，取消報名就在送出報名旁邊，
   一個手滑的距離；現在它們在視覺上分屬兩群，把寬度也讓給了主要動作。 */
.register-actions .action-btn--danger { flex: 0 0 auto; padding: 0 20px; }
.register-actions .action-btn:not(.action-btn--danger) + .action-btn--danger { margin-left: auto; }
.action-btn {
  flex: 1;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 左右內距不是裝飾，是換行的門檻。這種鈕是 flex:1（basis 0），空間不夠時會一路壓到
     min-content——而 white-space: nowrap 的 min-content 就是文字本身的寬度，於是文字會
     直接貼上圓角邊框。375px 的報名確認頁實測過：三顆並排時「編輯個人資料」的左右內距
     被壓到 0px，看起來像壞掉的膠囊。給了內距之後 min-content 變寬，擠不下時 flex-wrap
     會把最後一顆換到下一行，而不是三顆一起變形；空間夠時寬度仍由 flex 分配，外觀不變。 */
  padding: 0 14px;
  border: 1px solid #E0E0E0;
  border-radius: 22px;
  background: var(--color-surface);
  color: var(--color-text-body);
  font-size: 15px;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap; /* 「⌫ 刪除活動」在窄按鈕內不折成兩行 */
}
.action-btn--primary {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}
.action-btn--secondary {
  border-color: var(--color-primary);
  color: var(--color-primary);
  background: var(--color-surface);
}
.action-btn--danger {
  border-color: var(--color-danger); /* 框線維持設計稿的淺珊瑚 */
  color: var(--color-danger-text);   /* 標籤是要讀的文字，走可讀的深紅 */
  background: var(--color-surface);
}
.action-btn--subtle { flex: 0 0 auto; padding: 0 20px; border-style: dashed; }

/* ---------- 分組與晉級分頁（PDF p89–91） ---------- */
.groups-filter { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.groups-filter select {
  height: 34px;
  padding: 0 8px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font: inherit;
  font-size: 14px;
}
.reg-list__group { flex: 0 0 auto; font-size: 13px; color: var(--color-text-body); }
.groups-assign label { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 14px; color: var(--color-text-strong); white-space: nowrap; } /* 窄右欄時 label 文字保持整行、控制項換行，不得逐字直排 */
.groups-assign select {
  height: 38px;
  padding: 0 8px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font: inherit;
  font-size: 14px;
}
.groups-round-chip {
  display: inline-flex;
  align-items: center;
  height: 30px;
  padding: 0 12px;
  border: 1px solid var(--color-status-open);
  border-radius: var(--radius-sm);
  color: var(--color-status-open);
  font-size: 14px;
}
.forms-actions form { display: contents; } /* 匯出表單融入按鈕列 flex */
.group-settings__section { padding: var(--space-2) 0; border-bottom: 1px solid var(--color-border); }
.group-settings__section:last-of-type { border-bottom: 0; }
.group-settings__sub { display: block; margin: 8px 0 0 24px; font-size: 14px; }
.group-settings__rows { margin-top: var(--space-1); }
.group-settings__row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 8px; } /* RWD P3：窄對話框內折行 */
.group-settings__row label { flex: 0 0 auto; font-size: 14px; color: var(--color-text-strong); }
.group-settings__row input[name$=".Name"] {
  flex: 1 1 auto;
  height: 36px;
  padding: 0 10px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 14px;
}

/* ---------- 後台報名表格兩層式（活動後台頁面.docx 內容稿） ---------- */
/* 預覽層：參加者視角唯讀表單（fieldset[disabled] 鎖互動，外觀維持一般表單） */
.form-preview {
  margin: 0 0 var(--space-3);
  padding: 0;
  border: 0;
}
.forms-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}
.forms-actions__edit { flex: 1 1 auto; }
/* 段首說明與它點名的動作同一排：說明句寫著「請按〇〇」時，那顆鈕就該在句子旁，
   不是在三個畫面高的預覽下面。窄螢幕自動換行成上下兩排，按鈕靠左貼齊說明。 */
.wizard-section__lead {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
.wizard-section__lead .wizard-section__note { margin: 0; }
/* .action-btn 的基底是 flex:1（為了填滿按鈕列），放進這一排會被撐成半個版面寬；
   這裡要的是貼著文字的一顆鈕，因此改回自然寬度 */
.wizard-section__lead .action-btn { flex: 0 0 auto; padding: 0 20px; }
/* 停用態按鈕的統一灰態（發放鎖定期的「確認發放」鈕等） */
.action-btn:disabled,
.btn-primary:disabled {
  background: var(--color-text-disabled);
  border-color: var(--color-text-disabled);
  color: #fff;
  cursor: not-allowed;
}

/* 對話框（原生 dialog；figma：頂部青色條、置中卡片）
   定位明確寫死為 fixed 置中：實測 UA 樣式在部分情境給 absolute，
   頁面捲動後開啟的對話框會以文件座標置中、整段跑出視窗頂（標題被切掉）。 */
.modal {
  position: fixed;
  inset: 0;
  margin: auto;
  height: fit-content;
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  width: 400px;
  border: none;
  border-top: 6px solid var(--color-primary);
  border-radius: var(--radius-sm);
  padding: var(--space-4, 32px) var(--space-3) var(--space-3);
  text-align: center;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
}
.modal::backdrop { background: rgba(32, 32, 32, 0.45); }
/* 對話框開啟動畫（fade 加微上移）：原生 dialog 從 display:none 切入，一般 transition
   吃不到起始幀，@starting-style 補上（Chrome/Edge 125+）；不支援的瀏覽器直接顯示，
   屬漸進增強、無退化。transform 疊在 margin:auto 置中之上，不影響定位。 */
.modal[open] { transition: opacity .18s ease, transform .18s ease; }
.modal[open]::backdrop { transition: opacity .18s ease; }
@starting-style {
  .modal[open] { opacity: 0; transform: translateY(8px); }
  .modal[open]::backdrop { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .modal[open], .modal[open]::backdrop { transition: none; }
}
/* 寬版對話框（figma p89–91：分組與晉級設定等 560px），必須宣告在 .modal 之後，否則同特異度會被 width:400px 蓋掉 */
.modal--wide { width: 560px; }
.modal__title { font-size: 19px; font-weight: 700; color: var(--color-text-strong); margin-bottom: var(--space-2); }
.modal__text { font-size: 14px; color: var(--color-text-body); margin-bottom: var(--space-2); }
/* 說明段落靠左：對話框整體置中（標題、按鈕）是設計稿的樣子，但置中的多行說明每一行的
   起點都在浮動，而括號裡的補述又常把最後一兩個字擠成單獨一行（匯出視窗實際看到的是
   「連結）。」自己佔一行）。多行的說明段落改靠左，短句維持置中。 */
.modal__text--start { text-align: left; }
.modal__text--danger { color: var(--color-danger-text); }
/* 補充註記：語氣比內文更輕，用在成功情境下的「萬一沒收到信」這類提醒——
   那不是錯誤，套 --danger 會把紅色的警示意味帶進報名成功的畫面 */
.modal__text--note { color: var(--color-text-muted); font-size: 13px; }
/* 對話框內的成功回條（匯出已開始下載等），與 --danger 對稱；綠色沿用 readiness-status--ok 那一組 */
.modal__text--ok { color: #2E7D32; }
.modal__field { display: block; font-size: 14px; color: var(--color-text-strong); margin-bottom: var(--space-2); }
.modal__field select, .modal__input {
  display: block;
  width: 70%;
  height: 38px;
  margin: 8px auto 0;
  padding: 0 12px;
  border: 1px solid var(--color-text-disabled);
  border-radius: var(--radius-sm);
  font-size: 14px;
  text-align: center;
}
.modal__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: center; margin-top: var(--space-3); }
.modal__actions--single { justify-content: center; }
/* 底排左右分立：「取消」固定左下、主要動作靠右（0818 測試回饋：匯出視窗的關閉鈕位置要一致） */
.modal__actions--split { justify-content: space-between; }
/* 右側可以放不只一顆主要動作（匯出對話框的 zip 與 XLSX 是同一件事的兩種格式）：
   包成一組再靠右，「取消」才不會夾在兩個選項中間；窄螢幕下這一組自己換行，不拆散 */
.modal__actions__group { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.modal__btn {
  min-width: 120px;
  height: 40px;
  /* 文字不折行：「匯出含檔案（zip）」這類長標籤在固定高按鈕內折行會擠壓溢出，改讓按鈕自然加寬 */
  white-space: nowrap;
  padding: 0 16px;
  border: none;
  border-radius: var(--radius-sm);
  background: #DDF4FC;
  color: var(--color-text-strong);
  font-size: 15px;
  cursor: pointer;
}
.modal__btn--primary { background: var(--color-primary); color: #fff; }

.field textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--color-text-disabled);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font-size: 14px;
  font-family: inherit;
}
.field select {
  width: 100%;
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--color-text-disabled);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font-size: 14px;
}
/* ---------- 主辦方主題（青綠系；tokens 覆蓋讓大標題/強調色跟著換） ---------- */
.app-shell--host {
  --color-text-title: var(--color-text-title-host);
  --rail-decor-dark: #00596C;
}

/* ---------- 活動洞察（figma：活動方_管理活動_活動洞察） ---------- */
.insight-banner {
  display: flex;
  flex-wrap: wrap; /* RWD P0：窄幅折行；gap 收斂屬 P3（桌機可見） */
  gap: var(--space-6);
  align-items: center;
  padding: 20px 28px;
  margin-bottom: var(--space-3);
  border-radius: var(--radius-sm);
  background: #0B4B57;
  color: #fff;
  font-size: 17px;
}
.insight-banner strong { color: var(--color-accent); font-size: 26px; margin: 0 4px; }
.insight-layout {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--space-3);
  align-items: start;
}
.insight-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}
.insight-card {
  background: var(--color-surface);
  border-radius: var(--radius-sm);
  padding: 14px 18px;
  display: flex;
  flex-direction: column;
}
.insight-card__label { font-size: 14px; color: var(--color-text-strong); margin-bottom: 10px; }
/* 數字錨在卡片底部：同列卡片標題折行行數不同時（如「總人數」1 行 vs「隊伍組數」2 行），大數字仍對齊 */
.insight-card__value { margin-top: auto; font-size: clamp(24px, 8vw, 32px); font-weight: 700; color: var(--color-text-strong); text-align: center; } /* RWD P3：≥400px 恆 32px */
.insight-card__value span { font-size: 15px; font-weight: 400; }
.insight-chart {
  background: var(--color-surface);
  border-radius: var(--radius-sm);
  padding: 14px 18px;
}
.insight-chart__title { font-size: 14px; color: var(--color-text-strong); margin-bottom: 8px; }
/* 圖表橫捲僅限 ≤1024 單欄帶（見檔尾 media）；min-width 若放在基底，會讓 1440–1681 桌機
   雙欄右欄（實寬 ~499–638px）出現容器內捲，違反 ≥1440 零變更保證 */
.insight-chart { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.insight-chart svg { width: 100%; height: auto; display: block; }
/* 空資料時不需要 640px 寬的可捲動圖表；取消 min-width 讓置中的「尚無完成報名資料」留在可視範圍內（手機不會被右緣切掉）。
   雙類名提高特異度以蓋過 @media(max-width:1024) 的 .insight-chart svg{min-width:640px}（同特異度、宣告在後者會贏） */
.insight-chart.insight-chart--empty svg { min-width: 0; }
.insight-refresh { margin-top: var(--space-3); text-align: center; text-decoration: none; line-height: 40px; }

/* ---------- 報名資料 master-detail（figma：活動方_管理活動_報名資料） ---------- */
.reg-layout {
  display: grid;
  grid-template-columns: 340px minmax(0, 1fr);
  gap: var(--space-3);
  align-items: start;
}
.reg-list { background: var(--color-surface-alt); border-radius: var(--radius-sm); }
/* 大名單（數百筆）不得撐開整頁：桌機的名單欄黏在視窗內、清單自身捲動，
   點選後右側詳情永遠在可視範圍；≤1024 的單欄版型另有 40vh 規則，不在此列 */
@media (min-width: 1025px) {
  .reg-list { position: sticky; top: var(--space-3); max-height: calc(100vh - 2 * var(--space-3)); display: flex; flex-direction: column; }
  .reg-list > ul { overflow-y: auto; min-height: 0; }
}
/* 評分視角的 head 比一般名單多「階段下拉」與「評分狀態」兩件，340px 側欄一列塞不下會把
   狀態字壓成逐字直排；開 wrap 讓放不下的往下換行，一般視角（標題＋搜尋框）寬度足夠不受影響 */
.reg-list__head { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; padding: 14px; }
.reg-list__head h2 { font-size: 17px; color: var(--color-text-strong); }
.reg-list__head input {
  width: 170px;
  height: 34px;
  padding: 0 12px;
  border: none;
  border-radius: 17px;
  background: var(--color-surface);
  font-size: 13px;
}
.reg-list ul { list-style: none; margin: 0; padding: 0 12px 12px; }
.reg-list__item {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 10px 12px;
  margin-bottom: 8px;
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font-size: 13px;
  color: var(--color-text-body);
  text-decoration: none;
}
.reg-list__item--active { background: var(--color-primary); color: #fff; }
.reg-list__item--cancelled { opacity: 0.5; text-decoration: line-through; }
/* 選中時不套用取消態的淡化。兩條規則各自都合理，疊在一起卻是白字先被 opacity 洗成淡藍、
   底色也被洗成淡藍——實測對比只剩 1.26:1，幾乎看不見，而那正是使用者剛點開要看的那一列
   （從「已取消」篩選點進去複查時必然踩到）。刪除線保留：它才是「已取消」的語義來源，
   淡化只是加強而已。 */
.reg-list__item--active.reg-list__item--cancelled { opacity: 1; }
.reg-list__name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 審查旗標：符號本身不足以表意，靠 title 與 aria-label 補；顏色只是加強 */
.reg-list__flag { margin-right: 4px; color: var(--color-status-closing); }
.reg-list__empty { padding: 16px; font-size: 13px; color: var(--color-text-muted); }
/* 狀態篩選列與筆數：清單原本只有搜尋框，找「未送出」或「待補件」只能靠捲動 */
/* 簽到名單搜尋（現場報到用；只過濾顯示，統計數字仍取全體） */
.checkin-search { display: flex; align-items: center; gap: 8px; margin: var(--space-2) 0; }
.checkin-search input { flex: 1; max-width: 360px; height: 36px; padding: 0 12px; border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm); font: inherit; }
.reg-list__filter { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 14px 6px; }
.reg-list__filter .chip { font-size: 12px; padding: 4px 10px; }
/* 檢視範圍的可見說明（PM 定案：不能只靠 tooltip——手機與鍵盤操作看不到 hover） */
.reg-list__filter-hint { padding: 0 14px 12px; margin: 0; }
/* 匯出範圍選項（對話框）：兩個 radio 直排，各附摘要小字 */
.export-range { border: 0; padding: 0; margin: 0 0 var(--space-2); display: flex; flex-direction: column; gap: 8px; text-align: start; }
.export-range legend { padding: 0; margin-bottom: 4px; }
.export-range__option { display: flex; gap: 8px; align-items: flex-start; cursor: pointer; }
.export-range__option input { margin-top: 3px; flex: 0 0 auto; }
.export-range__option .field__hint { display: block; }
.reg-list__count { font-size: 12px; font-weight: 400; color: var(--color-text-muted); margin-left: 6px; }
.reg-detail { background: var(--color-surface-alt); border-radius: var(--radius-sm); padding: var(--space-3); }
.reg-detail__head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--space-1); margin-bottom: var(--space-3); } /* RWD P0：wrap、gap */
.reg-detail__head h2 { font-size: 19px; color: var(--color-text-strong); }
.reg-detail__actions { display: flex; flex-wrap: wrap; gap: 10px; } /* 窄右欄時按鈕改換行，不得把整頁撐出橫向捲軸 */
.reg-detail__actions .action-btn { flex: 0 0 auto; padding: 0 18px; height: 38px; }
.reg-export { margin-top: var(--space-3); border-radius: var(--radius-sm); }
/* 後台分頁（管理列 8、內容編輯列 9 起跳，自訂分頁與翻譯入口會再加）字多：縮小字級與間距，
   讓一般筆電（≥1280px）排得下，不再讓 D4 橫捲把後段分頁（問卷、協作、紀錄；活動場次、
   登記名單、繳件資料）切到畫面外——D4 原假設
   「桌機不觸發捲動」在 <~1650px 不成立（見 docs/design.md「RWD 設計理由與跨檔機制」D4）。公開頁分頁字少維持 20px。
   右緣加淡出遮罩當捲動提示：極窄幅仍需橫捲時看得出右邊還有分頁。 */
.page-tabs--backend,
.page-tabs--content-edit {
  gap: 12px;
}
/* 淡出遮罩同樣只在「還能往右捲」時掛（--masked 由 _Layout JS 切換），寬度 24px 蓋過 12px gap */
.page-tabs--backend.page-tabs--masked,
.page-tabs--content-edit.page-tabs--masked {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
}
/* 兩排字級一致（原設計即同為 20px；此處統一縮為 15px 以在 1280 排下並保持整齊） */
.page-tabs--backend .page-tabs__item,
.page-tabs--content-edit .page-tabs__item { font-size: 15px; margin-right: 0; }

/* 後台分頁手機版：改原生下拉選單（桌機維持橫排分頁；取代窄螢幕橫向捲動） */
.backend-nav-select { display: none; }
.backend-nav-select__control {
  flex: 1 1 auto; min-width: 0; height: 40px; padding: 0 12px;
  border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm);
  background: var(--color-surface); font-size: 15px; color: var(--color-text-strong);
}
.backend-nav-select__prefix { flex: 0 0 auto; font-size: 13px; color: var(--color-text-muted); }

/* ---------- 活動詳細頁（PDF p118/p58） ---------- */
.detail-topbar { display: flex; justify-content: space-between; align-items: flex-start; }
.detail-layout {
  display: grid;
  grid-template-columns: 340px minmax(0, 1fr);
  gap: var(--space-3);
  align-items: start;
}
.detail-brief {
  background: var(--color-surface);
  border-radius: var(--radius-sm);
  padding: var(--space-3);
}
.detail-brief__status { font-size: 14px; font-weight: 600; margin-bottom: 10px; }
.detail-brief__status--open { color: var(--color-status-open); }
.detail-brief__status--closing { color: var(--color-status-closing); }
.detail-brief__status--closed { color: var(--color-status-closed); }
.detail-brief__status--upcoming { color: var(--color-status-upcoming); }
.detail-brief__heading { font-size: 20px; font-weight: 700; color: var(--color-text-strong); margin-bottom: var(--space-2); }
.info-list--compact > div { margin-bottom: 8px; font-size: 14px; }
.detail-cta {
  display: block;
  width: 100%;
  height: 44px;
  line-height: 44px;
  margin-top: var(--space-2);
  border-radius: 22px;
  background: var(--color-primary);
  color: #fff;
  font-size: 15px;
  text-align: center;
  text-decoration: none;
}
.detail-cta--disabled { background: var(--color-text-disabled); color: #fff; cursor: not-allowed; }
.detail-cta--host { background: var(--color-surface); color: var(--color-primary); border: 1px solid var(--color-primary); line-height: 42px; }
/* 待補件：這是要學生立刻處理的事，用警示色與一般報名 CTA 區隔（按鈕文字本身已寫「待補件」） */
.detail-cta--supplement { background: var(--color-danger); }
/* 二次載入佔位的微光掃過：與靜態灰塊相比，「還在載入」與「載入完但空白」一眼可分 */
.detail-cta--loading {
  display: block;
  height: 44px;
  border-radius: 22px;
  background: linear-gradient(90deg, var(--color-surface-alt) 25%, var(--color-surface) 37%, var(--color-surface-alt) 63%);
  background-size: 400% 100%;
  animation: skeleton-shimmer 1.4s ease infinite;
}
@media (prefers-reduced-motion: reduce) {
  .detail-cta--loading { animation: none; background: var(--color-surface-alt); }
}
@keyframes skeleton-shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }
.detail-cta-hint { font-size: 13px; color: var(--color-text-muted); text-align: center; margin-top: var(--space-1); }
/* 分頁頁尾的報名入口：與上方內容以分隔線收尾，按鈕收到 320px 置中。
   .detail-cta 本身是滿寬的（那是為了填滿活動介紹分頁左欄的簡介卡），直接放進整幅的分頁面板
   會被拉成快一千像素的長條。 */
.detail-cta-footer {
  margin-top: var(--space-4, 32px);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  display: flex;
  justify-content: center;
}
.detail-cta-footer > div { width: 320px; max-width: 100%; }
.detail-cta-footer .detail-cta { margin-top: 0; }
.detail-brief__social { margin-top: var(--space-3); }
.detail-brief__social-heading { font-size: 15px; font-weight: 700; color: var(--color-text-strong); margin-bottom: 10px; }
.detail-brief__social-links { display: flex; gap: 16px; }
.detail-brief__social-links a { color: var(--color-text-strong); display: inline-flex; }
.detail-content { min-width: 0; }
.detail-content__cover { width: 100%; border-radius: var(--radius-sm); display: block; margin-bottom: var(--space-3); }
.detail-content__heading { font-size: 22px; font-weight: 700; color: var(--color-text-strong); margin-bottom: var(--space-2); }
.richtext { font-size: 15px; line-height: 1.9; color: var(--color-text-body); overflow-wrap: break-word; }
.richtext p { margin-bottom: 1em; }
.richtext h3 { font-size: 17px; color: var(--color-text-strong); margin: 1.2em 0 0.5em; }
/* RWD P0 富文字防禦：主辦方自編內容結構不可控，容器層收斂溢出（鐵律7 管線不動）；
   table 由 RichTextSanitizer 後處理包 .table-scroll（保留 AT〔輔助技術，如螢幕報讀器〕可讀的 table 語義，不用 display:block 蓋 table） */
.richtext img, .richtext iframe, .richtext video { max-width: 100%; height: auto; }

/* 時程時間軸（p58） */
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline__item {
  position: relative;
  display: grid;
  /* RWD P2：日期欄寬抽成變數。豎線 left = 欄寬 + 19px 讓線穿過 dot 中心
     （欄寬 + gap 8 + dot 欄半寬 12 − 線半寬 1 = +19）。
     收窄斷點只覆寫變數，豎線自動跟隨 */
  --timeline-when-w: 130px;
  grid-template-columns: var(--timeline-when-w) 24px minmax(0, 1fr);
  gap: 8px;
  padding-bottom: var(--space-4, 32px);
}
.timeline__item::before {
  content: "";
  position: absolute;
  left: calc(var(--timeline-when-w) + 19px);
  top: 8px;
  bottom: -8px;
  width: 2px;
  background: #C9C9C9;
}
/* 最後一筆不畫豎線：前一筆的 ::before（bottom:-8）已延伸進最後圓點，圓點自然接上；原本 height:100% 會讓線越過末圓點往下懸空一段 */
.timeline__item:last-child::before { display: none; }
.timeline__when { text-align: right; }
.timeline__date { font-size: 18px; font-weight: 700; color: var(--color-text-strong); }
.timeline__time { font-size: 12px; color: var(--color-text-muted); }
.timeline__dot {
  position: relative;
  z-index: 1;
  width: 12px;
  height: 12px;
  margin: 6px auto 0;
  border-radius: 50%;
  background: #8A8A8A;
}
/* 最近一筆未過期時程以琥珀色強調（figma-screenshots 活動時程） */
.timeline__item--current .timeline__date { color: var(--color-accent); }
.timeline__item--current .timeline__dot { background: var(--color-accent); }
.timeline__card {
  background: var(--color-surface);
  border-radius: var(--radius-sm);
  padding: 16px 20px;
}
.timeline__title { font-size: 16px; font-weight: 700; color: var(--color-text-strong); margin-bottom: 8px; }
.timeline__desc { font-size: 14px; line-height: 1.8; color: var(--color-text-body); }

/* FAQ 摺疊：編號題列搭配細分隔線，展開答案為白底方塊（figma-screenshots 常見問題） */
.faq-list { counter-reset: faq; }
.faq-item { border-bottom: 1px solid var(--color-text-strong); }
.faq-item__q {
  list-style: none;
  cursor: pointer;
  padding: 18px 4px;
  font-size: 16px;
  font-weight: 500;
  color: var(--color-text-strong);
}
.faq-item__q::-webkit-details-marker { display: none; }
.faq-item__q::before { counter-increment: faq; content: counter(faq) ". "; }
/* 右緣展開指示：原設計把預設三角藏了之後，收合的題列看起來就是一行死文字，
   沒有任何線索可以點開；補一個隨開合旋轉的箭頭，編號版式不動 */
.faq-item__q::after { content: "▾"; float: right; color: var(--color-text-muted); transition: transform .15s; }
.faq-item[open] > .faq-item__q::after { transform: rotate(180deg); }
/* 滑過整列要有回饋：題列是整行可點的（原生 summary），但箭頭在最右緣、離題目文字近 700px，
   滑鼠停在題目上時若毫無變化，讀的人不會知道這一整行都能按。底色改白（同答案區的底色）
   讓可點範圍在滑過時整條浮出來，箭頭一併轉深。包在 (hover: hover) 裡的理由見檔案後段。 */
@media (hover: hover) {
  .faq-item__q:hover { background: var(--color-surface); border-radius: var(--radius-sm); }
  .faq-item__q:hover::after { color: var(--color-text-strong); }
}
.faq-item__a {
  margin: 2px 0 18px;
  background: var(--color-surface);
  border-radius: var(--radius-sm);
  padding: 16px 20px;
}

.activity-empty {
  padding: var(--space-6) 0;
  text-align: center;
  color: var(--color-text-body);
  opacity: 0.6;
}

.pager {
  display: flex;
  flex-wrap: wrap; /* 頁數多時換行，不撐破容器 */
  gap: var(--space-2);
  justify-content: center;
  align-items: center;
  margin-top: var(--space-3);
}
/* 跳號處的省略記號：不是可點的頁碼，樣式與 chip 區隔 */
.pager__gap { color: var(--color-text-muted); padding: 0 2px; }

/* ---------- 活動卡片網格 ---------- */
.activity-grid {
  display: grid;
  /* RWD P2：auto-fill 自然降欄，1160px 容器（1440+ 桌機）恆 3 欄且欄寬與 repeat(3) 全等；
     1280–1386 呈 2 欄，是 D2 預期的改善；容器 <584 降為 1 欄。3 欄門檻為視口 ≈1387px。
     min(280px,100%) 是 <344px 視口的防禦（280 硬地板會溢出，故退為滿寬單欄） */
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: var(--space-3);
  max-width: 1160px;
}
.activity-card {
  background: var(--color-surface);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  /* 整卡可點（stretched link）的定位基準 */
  position: relative;
  transition: box-shadow .15s ease;
}
/* 整卡可點：卡內唯一的動作連結以 ::after 蓋滿整卡。三處卡片（活動總覽、主辦方總覽、
   我的活動）都只有一顆同目的地的連結，沒有互相衝突的動作，蓋滿不會奪走其他控制項；
   hover 陰影加深提示整卡可互動，鍵盤焦點外框仍畫在原按鈕上 */
.activity-card__actions .btn::after { content: ""; position: absolute; inset: 0; border-radius: var(--radius-md); }
@media (hover: hover) {
  .activity-card:has(.activity-card__actions .btn):hover { box-shadow: 0 6px 20px rgba(30, 63, 125, .18); }
}
.activity-card__cover {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius-md);
  /* 底色是載入中的佔位：aspect-ratio 早就把版位撐好了（不會位移），但圖還沒解碼完的那一段
     時間裡那塊區域是全白的，在白卡片上看起來像圖破了。鋪一層灰讓它讀作「圖還在路上」。
     沒有圖的卡片另有 --placeholder 的漸層，寫在本規則之後，會蓋掉這層灰。 */
  background: var(--color-surface-alt);
}
/* 協作角色徽章（主辦方活動總覽）：只出現在受邀協作的卡片上，
   標題的 min-height 已吸收高度差，有無徽章的卡片仍對齊 */
.activity-card__role {
  margin: var(--space-2) 0 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--color-primary);
}
.activity-card__title {
  margin: var(--space-2) 0 0;
  font-size: 20px;
  font-weight: 700;
  color: var(--color-text-strong);
  line-height: 1.5;
  min-height: 60px;
}
.activity-card__meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap; /* 窄卡片時整段換行（狀態與日期各為一整塊），不讓文字中途斷字 */
  gap: 10px;
  margin-top: var(--space-1);
  font-size: 14px;
}
.activity-card__status { font-weight: 700; white-space: nowrap; }
.activity-card__status--open { color: var(--color-status-open); }
.activity-card__status--closing { color: var(--color-status-closing); }
.activity-card__status--closed { color: var(--color-status-closed); }
.activity-card__status--upcoming { color: var(--color-status-upcoming); }
/* 狀態與日期改由 flex gap 分隔、隱藏「｜」：窄卡片（帳號我的活動、主辦方活動列表）折行時不會留下懸空的分隔線 */
.activity-card__meta-sep { display: none; }
.activity-card__dates { color: var(--color-text-body); white-space: nowrap; }
.activity-card__actions {
  display: flex;
  justify-content: flex-end;
  /* 貼卡片底部。標題的一到兩行由 min-height 吸收了，但狀態列沒有——帶截止時刻的活動
     會折成兩行（「報名已截止」與日期各佔一行），同一列卡片的按鈕因此差了一整行的高度，
     一整排看起來高高低低。grid 的 stretch 讓同列卡片等高，auto 邊界再把按鈕壓到底，
     不論上面多幾行都齊平。padding 維持原本與上一段的間距下限 */
  margin-top: auto;
  padding-top: var(--space-3);
}

/* ---------- 按鈕 ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  padding: 0 var(--space-4);
  border-radius: var(--radius-pill);
  font-size: 14px;
  border: 1px solid transparent;
}
.btn--outline {
  background: var(--color-surface);
  border-color: var(--color-border-strong);
  color: var(--color-text-strong);
  min-width: min(160px, 100%); /* RWD P0：窄容器內不撐破 */
}
@media (hover: hover) {
  .btn--outline:hover { border-color: var(--color-text-strong); }
}
.btn--primary {
  background: var(--color-primary);
  color: #fff;
  font-weight: 700;
}

/* ---------- 建立活動精靈（figma p8/p26；v1 單頁縱列） ---------- */
.wizard-steps {
  display: flex;
  gap: 8px;
  margin: var(--space-3) var(--space-3) var(--space-2);  /* 頂部留白：與上方「建立活動」標題原本貼死（0px），加 space-3 不再擠 */
  padding: 0;
  list-style: none;
}
.wizard-steps__item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--color-text-muted);
}
.wizard-steps__item:not(:last-child)::after {
  content: "";
  display: inline-block;
  width: 56px;
  height: 1px;
  background: var(--color-text-disabled);
}
.wizard-steps__dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--color-primary);
  border-radius: 50%;
  color: var(--color-primary);
  font-weight: 700;
}
.wizard-steps__item--active { color: var(--color-primary); }
.wizard-steps__item--active .wizard-steps__dot { background: var(--color-primary); color: #fff; }

.wizard-section__title { margin: var(--space-3) 0 var(--space-2); font-size: 18px; color: var(--color-text-strong); }
.wizard-section {
  max-width: 720px;
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface);
  border-radius: var(--radius-sm);
}
.wizard-section--readonly { color: var(--color-text-body); }
.wizard-section__note { margin: 0 0 var(--space-2); font-size: 14px; color: var(--color-text-body); }
.wizard-columns { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.wizard-columns__heading { font-size: 14px; color: var(--color-text-strong); border-bottom: 1px solid var(--color-text-disabled); padding-bottom: 6px; }
.wizard-list { margin: 8px 0 0; padding-left: 20px; font-size: 14px; line-height: 2; }
.wizard-section .btn-primary { max-width: 320px; }
/* 後台主按鈕統一 320px 上限（含對話框內）：主辦方後台以 app-shell--host、管理後台以 brand-rail--admin 為標記；
   學生端與公開頁不在此規則內（wizard-section 另涵蓋學生端的精靈版式，兩條都要留） */
.app-shell--host .btn-primary,
.app-shell:has(.brand-rail--admin) .btn-primary { max-width: 320px; }
.field__hint { display: block; margin-top: 4px; font-size: 12px; color: var(--color-text-muted); }
/* display: block 會蓋過 hidden 屬性的 UA 規則，這條把 hidden 的語義補回來——
   建構器文件連結的檔案欄提示（JS 依型別切換）與同意欄門檻的提示區都靠 hidden 收合 */
.field__hint[hidden] { display: none; }
/* 說明句與「下一個欄位」之間要拉開。不在 .field 裡、獨立掛在區塊上的說明（例如報名起訖日
   下面那句「建立後可在賽程編輯調整」）距離上一組欄位 4px、距離下一欄的 label 也差不多，
   兩邊等距時讀者分不出這句是在說上面還是下面。兄弟選擇器只會命中這種獨立的情形——
   在 .field 內部時說明是最後一個子元素，配不到後面的欄位。 */
.field__hint + .field,
.field__hint + .field-row-2,
.field__hint + .pfield { margin-top: var(--space-2); }
/* 需要留意的後果（例如可見性切換）：這個修飾詞先前只在 Razor 用過、CSS 沒有定義，等於沒有效果 */
.field__hint--warn { color: var(--color-danger-text); font-weight: 700; }
/* 封面選檔預覽：比例與卡片、公開頁封面一致（3:2 裁切），寬度收到 320px——
   這是「我挑的是不是這張」的確認，不是排版預覽，不需要佔滿欄寬 */
.cover-preview {
  display: block;
  width: 320px;
  max-width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  margin-top: var(--space-2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
}
/* display: block 會蓋過 UA 樣式表的 [hidden]（作者樣式恆優先於 UA 樣式，與 specificity 無關），
   沒有這條的話待命中的預覽 <img hidden> 會以無 src 的破圖框露出來 */
.cover-preview[hidden] { display: none; }
.filter-row__create { margin-left: auto; }

/* ---------- 後台內容編輯列、富文字編輯頁 ---------- */
.page-tabs--content-edit { margin-top: 4px; } /* 原 -8px（為 20px 分頁調的）會與上排底線重疊；縮小字級後改為小正值，兩排乾淨分開 */
/* 前綴標籤（內容編輯：）：分頁 __item 有 padding-bottom:6 + border-bottom:4 = 10px 底部空間把文字往上頂，
   標籤補相同的 10px 讓其文字與分頁文字對齊（否則置中對齊下標籤文字會低 5px）。white-space 防壓縮直排 */
.page-tabs__label { font-size: 13px; color: var(--color-text-muted); align-self: center; flex: 0 0 auto; white-space: nowrap; padding-bottom: 10px; }
.content-panel .jodit-container { max-width: 860px; background: #fff; }
/* 這裡刻意不加 min-inline-size: 0。fieldset 的瀏覽器預設確實是 min-inline-size: min-content
   （會拒絕縮到內容最小寬度以下），賽程編輯頁在英文語系的 375px 下也真的量到整條撐成 384px——
   但那個 384 是**內部有東西縮不下去**造成的，不是 fieldset 本身的毛病：真正的原因是
   .phase-form-links 少了 flex-wrap，兩顆 nowrap 的 chip 撐開了 min-content。
   逐項實測（375px、英文、賽程編輯頁）：只補 flex-wrap，scrollWidth 360 完全收斂；
   只補 min-inline-size: 0，fieldset 縮回 244 但頁面仍溢出 64px。歸零只會把症狀藏起來，
   讓真正縮不下去的內容繼續溢出而外框看起來正常，所以不留這條。 */
.batch-row { margin-bottom: var(--space-2); padding: var(--space-2); border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm); }
.batch-row legend { padding: 0 6px; font-size: 13px; color: var(--color-text-muted); }
/* 報名表單建構器的欄位卡改成兩欄。單欄堆疊時每張卡約 480px 高，套用範本後十幾欄疊起來
   頁高破萬像素——要調第十欄得往下捲五千像素，改完再捲回去確認。短控制項（類型與格式設定、
   字數上限與自動帶入）兩兩並排後每張卡少掉兩列。欄位名稱、選項、連結、檔案限制與動作列
   維持整列：它們不是內容較長就是本身含多個控制項，擠成半欄只會換來折行。
   隱藏中的 .field（型別不適用時由 JS 加 hidden）不佔格線，欄位不會空一格。 */
.batch-row[data-field-row] {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 var(--space-3);
  align-items: start;
}
.batch-row[data-field-row] > .field:first-of-type,
.batch-row[data-field-row] > [data-options-field],
.batch-row[data-field-row] > [data-linkurl-field],
.batch-row[data-field-row] > [data-file-rules],
.batch-row[data-field-row] > .field__hint,
.batch-row[data-field-row] > .settings-row__actions { grid-column: 1 / -1; }
/* 卡內的行距收一點：兩欄之後上下列變多，維持 16px 會把省下來的高度又吃回去 */
.batch-row[data-field-row] > .field { margin-bottom: 10px; }
/* 窄幅收回單欄（斷點表 ≤900px「雙欄版型收為單欄」）。少了這一條，375px 下每欄只剩 101px，
   「類型」「格式設定」那幾個下拉會窄到讀不出選了什麼——省高度是為了好調欄位，不是把它壓扁。 */
@media (max-width: 900px) { .batch-row[data-field-row] { grid-template-columns: minmax(0, 1fr); } }
/* 隊伍人數上下限：下限與上限並排、數字框收窄。
   原本 class="field team-size-bounds" 只吃 .field 規則（label 獨立成行、input width:100%），
   會變成兩個全寬大框各只裝一個數字，過於鬆散。 */
.team-size-bounds { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; }
.team-size-bounds .field__label { flex: 1 0 100%; margin-bottom: 2px; }
.team-size-bounds label { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: 14px; color: var(--color-text-strong); }
.team-size-bounds input { width: 88px; }

/* ===== 排版微調（各頁個別問題的局部修正） ===== */
/* 數字/日期/時間欄位不吃 .field input 的滿版規則（否則 2 位數或日期框被撐成整行、鬆散） */
.field input[type="number"], .field input[type="date"], .field input[type="datetime-local"] { width: auto; min-width: 130px; max-width: 220px; }
/* 內聯順位下拉（Ranking「第 N 順位」）不吃 .field select 的滿版 */
.field .field__choice select { width: auto; }
/* 活動卡片動作鈕：補間距，並允許換行，避免兩顆按鈕相貼或溢出卡片 */
.activity-card__actions { gap: var(--space-2); flex-wrap: wrap; }
/* 頭像下拉卡片：長 email 或名稱可斷行，不外溢固定寬卡片 */
.account-menu__email, .account-menu__name { overflow-wrap: anywhere; }
/* 「我的活動」頁首（無中間搜尋欄）：標題撐滿把帳號區推到最右，與公開頁一致 */
.track-head { flex: 1 1 auto; min-width: 0; }
/* 精靈雙欄：右欄依內容收合高度，避免被拉高留大片空白 */
.wizard-columns { align-items: start; }
/* 分組設定對話框：階段紀錄標題與保底紀錄輸入框，套用與其他列相同的控制項樣式 */
.group-settings__row input[name$=".Title"], .group-settings__row input[name="BaselineRecordTitle"] { flex: 1 1 auto; height: 36px; padding: 0 10px; border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm); }
/* 獎項指派列的日期框與同列 select 同高 */
.groups-assign input[type="date"] { height: 38px; padding: 0 8px; border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm); }
/* 紀錄與證明頁的發放與已發放表格（原本無樣式、退回瀏覽器裸表格） */
.records-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.records-table th { text-align: left; padding: 8px 12px; border-bottom: 1px solid var(--color-text-disabled); color: var(--color-text-strong); font-weight: 600; white-space: nowrap; }
.records-table td { padding: 10px 12px; border-bottom: 1px solid var(--color-text-disabled); }
.records-date input[type="date"] { max-width: 200px; }
/* 學生端驗證連結（/account/records 總覽與報名頁紀錄分頁）：readonly URL、複製鈕、停用態、動作欄 */
.record-link { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; }
.record-link__url { width: 300px; max-width: 100%; height: 32px; padding: 0 8px; border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm); font-size: 13px; color: var(--color-text-body); background: var(--color-surface); }
.record-revoked { color: var(--color-text-muted); font-size: 13px; }
.record-holder { display: block; font-size: 12px; color: var(--color-text-muted); }
.record-actions form { display: inline-block; margin: 0 6px 0 0; }
.record-actions .chip { cursor: pointer; }
/* 公開驗證頁（/verify/{token}）：置中卡片、平台背書 */
.verify-card { max-width: 560px; margin: 0 auto; padding: var(--space-3); background: var(--color-surface); border: 1px solid var(--color-text-disabled); border-radius: var(--radius-md); }
.verify-card__badge { display: inline-block; margin: 0 0 var(--space-2); padding: 4px 14px; border-radius: 9999px; background: #E6F7EE; color: #1F7A4D; font-size: 13px; font-weight: 700; }
.verify-card__endorsement { margin: var(--space-2) 0 0; padding-top: var(--space-2); border-top: 1px dashed var(--color-text-disabled); font-size: 13px; color: var(--color-text-muted); }
/* 密碼欄眼睛鈕改用 top 定位（對齊 label 與 input），避免驗證錯誤訊息出現、.afield 變高時被推到錯誤行 */
.afield__eye { top: 24px; bottom: auto; }
/* 報名資料頁「審查註記與退回補件」表單：補 flex 版面與控制項樣式（原本 label 直接包裸控制項、無樣式） */
.review-note-form, .supplement-box form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 14px; margin-top: 8px; }
.review-note-form > label, .supplement-box form > label { display: flex; flex-direction: column; gap: 4px; font-size: 14px; color: var(--color-text-strong); }
.review-note-form select, .review-note-form input, .supplement-box form select, .supplement-box form input { height: 36px; padding: 0 10px; border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm); font-size: 14px; background: #fff; }
/* 備註欄吃整列剩餘寬並可收縮：固定 min-width 在右欄詳情窄於 220px 時會把整頁撐出水平捲動
   （報名資料頁 1024～1100px 實測），改成 label 帶彈性基準寬、輸入框跟著 label 收縮 */
.review-note-form label:has(input[name="note"]), .supplement-box form label:has(input[name="note"]) { flex: 1 1 200px; max-width: 100%; min-width: 0; }
.review-note-form input[name="note"], .supplement-box form input[name="note"] { width: 100%; min-width: 0; }
/* 審查原因選項維護：原因輸入框與「移除」鈕同列，輸入框吃剩餘寬度 */
.reason-row { display: flex; align-items: center; gap: 8px; }
.reason-row input:not([type="hidden"]) { flex: 1; min-width: 0; }
/* 成對欄位（起訖日期/時間）並排 */
.field-row-2 { display: flex; flex-wrap: wrap; gap: 0 20px; }
.field-row-2 > .field { flex: 1 1 200px; }
/* 等權並列的 pill 按鈕等寬（如 login-stuck 兩顆） */
.auth-actions--equal .btn-pill { flex: 1 1 0; text-align: center; }
/* typed-phase：報名階段列以琥珀色邊區隔；組隊設定橫排；公開 stepper 起訖日期 */
.batch-row--registration { border-left: 3px solid #FFB321; }
.phase-team-settings { display: flex; flex-wrap: wrap; gap: 8px 20px; align-items: center; }
/* 勾選項獨佔一列：它的文案比兩個人數欄長得多，三者同列時「下限」被擠在它右邊、「上限」
   被推到下一列的最左，同一組的兩個欄位因此左右錯開。分列後兩欄並排，輸入框自然對齊。 */
.phase-team-settings > label:first-child { flex: 0 0 100%; }
.phase-team-settings input[type="number"] { width: 80px; margin-left: 6px; }
.register-steps__dates { display: block; font-size: 11px; color: var(--color-text-muted); }
.phase-panel__dates { margin-left: 8px; font-size: 13px; font-weight: 400; color: var(--color-text-muted); }
/* 首頁/列表裝飾插圖置底，內容在其上，避免壓過卡片與分頁。
   dialog 必須排除：這條的特異度 (0,2,0) 會把 .modal 的 position: fixed 蓋成 relative，
   對話框因此隨頁面捲動跑出視窗（開啟時已在 top layer，本就不需要 z-index 墊高） */
.content-panel__illustration { z-index: 0; }
.content-panel > *:not(.content-panel__illustration, dialog) { position: relative; z-index: 1; }
/* 活動卡片無縮圖時的預設底圖（取代破圖 icon） */
.activity-card__cover--placeholder { background: linear-gradient(135deg, #E9F0FF 0%, #CFE0FF 100%); display: flex; align-items: center; justify-content: center; }
.activity-card__cover--placeholder::after { content: "bonder"; font-weight: 700; font-size: 20px; letter-spacing: 1px; color: #9DB4E8; }
/* 階段頁標題層級：階段名(h3)、報名場次(h4)遞減字級，與頁面 h2 區隔 */
h3.detail-content__heading { font-size: 18px; }
h4.detail-content__heading { font-size: 16px; }
/* 學生端參賽紀錄（無右欄 rail）內容限寬，避免橫跨整個面板留大片空白 */
.register-panel .register-main { max-width: 760px; }

/* ---------- 管理後台（admin；figma 風格延伸） ---------- */
.topbar__title--admin { color: #1E3F7D; }
/* 靠右推齊：頭像選單固定在右上角，與各頁的帳號區位置一致（0818 測試回饋；
   身分標示與版本資訊同組靠右，頭像為最右元素） */
.admin-identity { display: flex; align-items: center; gap: 12px; font-size: 14px; color: var(--color-text-body); margin-left: auto; }
.admin-table-wrap { overflow-x: auto; }
/* RWD P0：通用表格捲動容器（比照 admin-table-wrap；sanitize 後處理的富文字 table 也包這個） */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* RWD P4：設定 min-width 讓窄視口在 admin-table-wrap 內穩定橫捲（依 D1，admin 頁面以可捲動視為可用），
   欄距不再被壓縮；桌機容器 ≥720 不觸發 */
.admin-table { width: 100%; min-width: 720px; border-collapse: collapse; background: var(--color-surface); border-radius: var(--radius-sm); font-size: 14px; }
.admin-table th, .admin-table td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--color-text-disabled); }
.admin-table th { color: var(--color-text-strong); white-space: nowrap; }
.admin-role-form { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; } /* RWD P4：內嵌表單撐格的儲存格垂直堆疊 */
/* 兩張表單上下相鄰時要隔開：成效統計頁把「搜尋活動」與「為活動建立統計資料」排在一起，
   零間距的話兩個各自獨立的動作黏成一整塊，第二排開頭的說明文字看起來像在標示第一排那個欄位。
   只加在後面那一張，第一張與上方說明之間的間距維持原樣。 */
.admin-role-form + .admin-role-form { margin-top: var(--space-2); }
/* label 是 flex item，不設 max-width 時會隨長 option 的 select 固有寬直出視口
   （成效統計的建列下拉裝著 30 字活動標題）；壓回容器寬後全域 select 的 max-width 接手截斷 */
.admin-role-form label { min-width: 0; max-width: 100%; }
.admin-role-form select, .admin-role-form input { height: 32px; padding: 0 8px; border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm); font-size: 13px; }

/* 會員統計的分層數字列。刻意不重用 .admin-table：那個類別為了讓寬表格穩定橫捲而設了
   min-width: 720px，兩欄的小表因此會在手機上莫名其妙橫向捲動——這裡的內容只有標籤與數字，
   窄視口該做的是把數字換行到標籤下方，不是捲。用 dl 是因為這正是名稱對數值的語義。 */
.stat-list { margin: var(--space-3) 0 var(--space-4); display: grid; gap: 4px; }
.stat-list__group, .stat-list__row {
  display: flex; flex-wrap: wrap; gap: 4px 16px; align-items: baseline; justify-content: space-between;
  padding: 10px 12px; background: var(--color-surface); border-radius: var(--radius-sm);
}
/* 分組列（會員帳號、員工帳號、帳號總數）：與子項以粗細和上緣線分層，不靠縮排硬撐 */
.stat-list__group { font-weight: 600; color: var(--color-text-strong); border-top: 1px solid var(--color-text-disabled); border-radius: 0; }
.stat-list__group--total { border-top-width: 2px; }
/* 子項縮排。窄視口收窄但不歸零：完全平齊會讓分層帳看起來像一串無關的數字 */
.stat-list__row { margin-left: 24px; }
.stat-list__label { margin: 0; }
.stat-list__hint { display: block; font-size: 12px; font-weight: 400; color: var(--color-text-muted); }
/* 數字用等寬數字字形，逐列的位數才對得齊（分層帳要一眼看出哪一項佔多數） */
.stat-list__value { margin: 0; font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums; }
/* 未知角色那一列：出現本身就是異常訊號，用深紅文字色標出來（框線與徽章用色不動） */
.stat-list__row--alert .stat-list__label, .stat-list__row--alert .stat-list__value { color: var(--color-danger-text); }
.stat-list__row--alert .stat-list__hint { color: var(--color-danger-text); }
@media (max-width: 480px) {
  .stat-list__row { margin-left: 12px; }
  .stat-list__value { font-size: 18px; }
}

/* ---------- auth 分割版式（PDF p92/p111/p116/p117） ---------- */
/* 欄比對齊舊版正式站（左視覺欄約 57%）；左欄整面是官方資產 login_visual.svg 以
   center/cover 鋪滿（同 bonder.com.tw 的鋪法），漸層背景與 logo、slogan 都在圖裡 */
.auth-split { display: grid; grid-template-columns: 4fr 3fr; min-height: 100vh; background: #fff; }
.auth-hero { position: relative; overflow: hidden; background: #05BAF2 url("/img/login_visual.svg") center / cover no-repeat; }
.auth-side { position: relative; display: flex; align-items: center; justify-content: center; padding: var(--space-6) 24px 110px; }
.auth-form { width: 360px; max-width: 100%; }
.auth-form__title { margin: 0 0 28px; font-size: 30px; font-weight: 700; color: #1E3F7D; }
.auth-form__desc { margin: -16px 0 28px; font-size: 13px; color: var(--color-text-body); }
.afield { margin-bottom: 24px; position: relative; }
.afield label { display: block; font-size: 13px; color: #939393; margin-bottom: 2px; }
.afield input { width: 100%; height: 34px; border: none; border-bottom: 1px solid #C9C9C9; font-size: 15px; padding: 0 30px 0 2px; background: transparent; border-radius: 0; transition: border-bottom-color .15s ease; }
.afield input:focus { outline: none; border-bottom-color: var(--color-primary); }
.afield__eye { position: absolute; right: 0; bottom: 5px; border: 0; background: none; color: #939393; cursor: pointer; padding: 2px; line-height: 0; }
/* Edge 對輸入中的密碼欄會畫自己的顯示密碼眼睛（::-ms-reveal），與站內的 .afield__eye 疊成兩顆；
   站內切換鈕涵蓋全部密碼欄且有無障礙狀態，故藏原生那顆。Firefox 不認這個選擇器會整條丟棄，所以獨立成規則 */
input[type="password"]::-ms-reveal, input[type="password"]::-ms-clear { display: none; }
/* 眼睛圖示隨狀態切換：遮蔽時是睜眼（按了會顯示）、明碼時加斜線（按了會隱藏）——
   沒有這條，明眼使用者只能靠密碼變明碼判斷狀態，圖示本身沒有回饋 */
.afield__eye .afield__eye-slash { display: none; }
.afield__eye[aria-pressed="true"] .afield__eye-slash { display: initial; }
.afield__error { font-size: 12px; color: #E4586A; }
/* 欄位規則提示（送出前就說清楚，不等後端退回）：與錯誤訊息同一行寬，顏色降一階 */
.afield__hint { display: block; margin-top: 4px; font-size: 12px; color: var(--color-text-muted); }
.btn-pill { display: inline-block; min-width: 120px; padding: 9px 28px; border-radius: 9999px; background: var(--color-primary); color: #fff; border: 1px solid var(--color-primary); font-size: 14px; text-align: center; cursor: pointer; text-decoration: none; }
.btn-pill--outline { background: #fff; color: var(--color-text-body); border-color: #C9C9C9; }
/* 主要按鈕的 hover 回饋：實底鈕微增亮、白底鈕微壓暗，.15s 過渡（站內慣例時長）——
   滑鼠使用者靠 hover 確認按鈕可點，先前只有零星按鈕有回饋（phase-reg__btn、
   file-selector-button），此處補齊四個主鈕家族並沿用同一套 brightness 語彙；
   停用態不回饋（aria-busy 送出中的降透明度樣式在 filter 之外，互不干擾） */
.btn-primary, .btn-pill, .btn--primary, .detail-cta { transition: filter .15s ease; }
/* 觸控裝置的 hover 殘留：手指點過之後，:hover 會留在那個元素上直到點了別的地方——按鈕維持
   增亮、卡片維持加深的陰影、chip 維持藍框，看起來像「這一個被選取了」。凡是會改變元素外觀、
   足以被誤讀成選取態的 hover，一律包進 (hover: hover)：桌機照舊，沒有 hover 能力的裝置就
   不長出來。連結變色那類影響小的維持原樣。:active 不必包——那是按下的當刻回饋，本來就適用觸控。
   同一份檔案裡 (pointer: coarse) 已經在調觸控目標，兩者是同一組裝置考量。 */
@media (hover: hover) {
  .btn-primary:hover:not(:disabled),
  .btn-pill:not(.btn-pill--outline):hover:not(:disabled),
  .btn--primary:hover,
  .detail-cta:hover:not(.detail-cta--disabled):not(.detail-cta--host) { filter: brightness(1.05); }
  .btn-pill--outline:hover:not(:disabled), .detail-cta--host:hover { filter: brightness(0.97); }
}
/* 按下瞬間再壓暗一階（hover 增亮的反向）：給「按下去了」的觸覺對應，放開即回 hover 態 */
.btn-primary:active:not(:disabled),
.btn-pill:active:not(:disabled),
.btn--primary:active,
.detail-cta:active:not(.detail-cta--disabled) { filter: brightness(0.95); }
.auth-actions { display: flex; gap: 16px; margin-top: 28px; flex-wrap: wrap; }
.auth-side__footer { position: absolute; bottom: 40px; left: 0; right: 0; display: flex; flex-wrap: wrap; gap: 24px; justify-content: center; font-size: 13px; padding: 0 var(--space-2); }
.auth-side__footer a { color: var(--color-text-body); text-decoration: none; }
.auth-side__footer a:hover { color: var(--color-primary); }
.auth-side__footer .auth-side__footer-strong { color: #135DAB; font-weight: 700; }
@media (max-width: 900px) { .auth-split { grid-template-columns: minmax(0, 1fr); } .auth-hero { display: none; } }

/* ---------- 使用者中心（活動軌跡；PDF p112 檢視/p145 編輯/p148 我的活動） ---------- */
.track-head__back { display: block; font-size: 13px; color: var(--color-text-muted); text-decoration: none; margin-bottom: 2px; }
.track-head__back:hover { color: var(--color-primary); }
.track-status--pending { color: #FFB321; }
.track-status--done { color: #04B2ED; }
.track-status--cancel, .track-status--disband { color: #939393; }
.track-status--error { color: #FF8284; }
/* 待補件：與一般完成狀態明顯區隔（顏色只是加強，文字本身已寫明「待補件」） */
/* 待補件升為填色徽章（其餘狀態維持純文字著色）：這是清單上唯一需要學生行動的狀態，
   且系統不寄補件通知信，卡片上的這一枚是主要的提醒入口，必須一眼可辨 */
.track-status--supplement {
  color: #B3283C;
  background: #FDECEE;
  border: 1px solid #E4586A;
  border-radius: var(--radius-pill);
  padding: 2px 10px;
}
.chip--track-open { border: 1px solid #FF8284; color: #FF8284; }
.chip--track-done { border: 1px solid #9382FF; color: #9382FF; }
.my-activities__empty { text-align: center; padding: var(--space-4) 0; color: var(--color-text-muted); }
/* 不覆寫 display：.btn 的 inline-flex 置中要保留，改成 inline-block 會讓 40px 高的按鈕文字貼頂（跑版） */
.my-activities__empty .btn { margin-top: var(--space-2); }
.profile-grid { display: grid; grid-template-columns: 300px 1fr; gap: var(--space-3); align-items: start; }
.profile-card { background: #fff; border-radius: var(--radius-md); padding: var(--space-3) var(--space-2); text-align: center; }
.profile-card__avatar { width: 120px; height: 120px; margin: 0 auto var(--space-2); border-radius: 50%; background: var(--color-text-disabled); color: var(--color-text-muted); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.profile-card__avatar img { width: 100%; height: 100%; object-fit: cover; }
.profile-card__name { margin: 0 0 2px; font-size: 18px; font-weight: 700; color: var(--color-text-strong); }
.profile-card__occupation { margin: 0 0 2px; font-size: 13px; color: var(--color-text-body); }
.profile-card__edit { display: block; margin: 0 16px var(--space-2); }
.profile-card__info { margin: 0; text-align: left; font-size: 13px; color: var(--color-text-body); }
.profile-card__info div { display: flex; gap: 2px; margin-bottom: 4px; }
.profile-card__info dt { color: var(--color-text-muted); flex-shrink: 0; }
.profile-card__info dd { margin: 0; word-break: break-all; }
.profile-card__section { text-align: left; font-weight: 700; font-size: 14px; color: var(--color-text-strong); margin: var(--space-2) 0 4px; }
.profile-card__list { text-align: left; margin: 0; padding-left: 18px; font-size: 13px; color: var(--color-text-body); }
.profile-card__bio { text-align: left; margin: 0; font-size: 13px; color: var(--color-text-body); white-space: pre-wrap; }
.profile-card__social { text-align: left; display: flex; gap: 10px; margin: 0; }
.profile-card__social a { color: #202020; }
.profile-fields { background: #fff; border-radius: var(--radius-md); padding: var(--space-3); }
.pfield { margin-bottom: var(--space-2); }
.pfield label { display: block; font-size: 13px; color: var(--color-text-strong); margin-bottom: 4px; }
.pfield input, .pfield select, .pfield textarea { width: 100%; min-height: 38px; padding: 6px 10px; border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm); font-size: 14px; background: #fff; }
.pfield textarea { resize: vertical; }
.pfield input:disabled { background: #F7F7F7; color: var(--color-text-body); }
.profile-fields__links { font-size: 13px; margin: var(--space-2) 0 0; }
.profile-edit-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); align-items: start; }
.profile-edit-card { background: #fff; border-radius: var(--radius-md); padding: var(--space-3); margin-bottom: var(--space-3); }
.profile-edit-card__title { font-weight: 700; font-size: 15px; color: var(--color-text-strong); margin: 0 0 var(--space-2); }
.profile-edit-card__upload { display: block; text-align: center; color: var(--color-primary); font-size: 13px; cursor: pointer; margin-bottom: var(--space-2); }
/* 視覺隱藏但保留可聚焦（display:none 與 hidden 會把元素踢出 Tab 序）；
   目前僅頭像上傳的 file input 使用，聚焦回饋走下一條的 :focus-within */
.visually-hidden-focusable { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.profile-edit-card__upload:focus-within { outline: 2px solid var(--color-primary); outline-offset: 2px; border-radius: 4px; }
.profile-edit-save { width: 100%; }
@media (max-width: 900px) { .profile-grid, .profile-edit-grid { grid-template-columns: minmax(0, 1fr); } }

/* ---------- 活動留言板 Tab（PDF p174–p176「提問與留言」） ---------- */
.comment { padding: var(--space-2) 0; }
.comment + .comment { border-top: 1px solid transparent; } /* 稿面留言間無分隔線，僅留白 */
.comment__head { display: flex; align-items: center; gap: 12px; }
.comment-avatar {
  width: 44px; height: 44px; border-radius: 50%; flex-shrink: 0;
  background: var(--color-text-disabled); color: #fff;
  display: inline-flex; align-items: center; justify-content: center; overflow: hidden;
}
.comment-avatar img { width: 100%; height: 100%; object-fit: cover; }
.comment--reply .comment-avatar { width: 36px; height: 36px; }
.comment__meta { display: flex; flex-direction: column; gap: 2px; }
.comment__nameline { display: inline-flex; align-items: center; gap: 6px; }
.comment__name { font-size: 15px; color: var(--color-text-strong); overflow-wrap: anywhere; }
/* 主辦方徽章：官方答覆與一般留言必須可辨（膠囊型、主色描邊，與分頁徽章同語彙） */
.comment__badge {
  padding: 0 8px; font-size: 11px; line-height: 18px; border-radius: 999px;
  border: 1px solid var(--color-primary); color: var(--color-primary); white-space: nowrap;
}
.comment__time { font-size: 12px; color: var(--color-text-muted); }
/* overflow-wrap：留言是使用者內容，長網址等無空白長字串會把整頁撐寬（與 .info-list dd 同慣例） */
.comment__content { margin: 10px 0 0; font-size: 14px; line-height: 1.7; color: var(--color-text-body); white-space: pre-wrap; overflow-wrap: anywhere; }
.comment__delete { margin-left: auto; }
.comment__delete button {
  border: 0; background: none; padding: 0; cursor: pointer;
  font-size: 12px; color: var(--color-text-muted);
}
.comment__delete button:hover { color: var(--color-danger); }
.comment__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: 10px; }
.comment__actions summary {
  list-style: none; cursor: pointer; font-size: 13px; color: var(--color-text-muted);
}
.comment__actions summary::-webkit-details-marker { display: none; }
.comment__replies summary::before { content: "──　"; color: var(--color-text-disabled); }
.comment__replies summary, .comment__replybox summary { display: inline-block; }
/* 收合時兩顆連結同行（p174「── 查看其他 2 則回覆　回覆」）；展開的那顆佔滿整行 */
.comment__replies, .comment__replybox { flex-basis: auto; }
.comment__replies[open], .comment__replybox[open] { flex-basis: 100%; }
.comment--reply { margin-left: 56px; padding: var(--space-1) 0; }
.comment__replybox form { margin-top: 10px; }

/* 發言框（p174 底部：頭像、圓角輸入、圓形送出鈕） */
.comment-form { display: flex; align-items: center; gap: 12px; margin-top: var(--space-3); }
.comment-form--reply { margin-top: 0; margin-left: 56px; }
.comment-form__name { font-size: 15px; color: var(--color-text-strong); flex-shrink: 0; }
.comment-form__input {
  flex: 1; min-height: 40px; padding: 8px 16px;
  border: 0; border-radius: var(--radius-pill);
  background: var(--color-surface); font-size: 14px; /* 面板底是 surface-alt 灰，輸入框用白底才顯形 */
  /* textarea 專用：字型不繼承、預設可拉伸會破版，捲軸交給 autogrow 控制 */
  font-family: inherit; line-height: 24px; resize: none; overflow-y: auto;
}
.comment-form__input:focus { outline: 2px solid var(--color-primary); }
.comment-form__send {
  width: 40px; height: 40px; border-radius: 50%; border: 0; flex-shrink: 0;
  background: var(--color-primary); color: #fff; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.comment-form__send:hover { filter: brightness(1.05); }
.comment-login-hint { margin-top: var(--space-3); font-size: 14px; color: var(--color-text-body); }
.comment-login-hint a { color: var(--color-primary); }

/* ---------- 設定與發布頁（figma p15）---------- */
/* 導覽 chip：外框膠囊（p12/p15，與內容分頁的底線樣式區隔） */
.page-tabs__item--settings {
  border: 1px solid var(--color-text-strong);
  border-radius: 999px;
  padding: 4px 16px;
}
.wizard-columns--settings { grid-template-columns: 5fr 7fr; align-items: start; }
/* 右欄「發布設定」與「活動分頁設定」兩卡直向堆疊，佔原本單卡的格位；間距與外層雙欄格同一 token */
.settings-card-stack { min-width: 0; display: grid; gap: var(--space-3); align-content: start; }
.settings-card {
  min-width: 0;
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: #fff;
}
.settings-card .wizard-section__title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-1);
}
.settings-summary {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 10px var(--space-2);
  margin: var(--space-2) 0 0;
  font-size: 14px;
}
.settings-summary dt { color: var(--color-text-muted); }
.settings-summary dd { margin: 0; color: var(--color-text-strong); }
.settings-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-wrap: wrap;
  padding: var(--space-1) 0 var(--space-2);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-2);
}
.settings-toggle > label { min-width: 0; max-width: 100%; }
/* 可見性下拉原本完全沒有樣式，是 19px 高的原生預設——全站其他下拉都是 38 到 40px。
   它是整個主辦後台後果最大的一個控制項（按下去活動就上架了），卻長得最不像控制項，
   在手機上更是一條難以命中的細線。比照 .field select 的規格補齊。 */
.settings-toggle select {
  max-width: 100%;
  height: 38px;
  padding: 0 10px;
  border: 1px solid var(--color-text-disabled);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font: inherit;
  font-size: 14px;
  color: var(--color-text-strong);
}
/* 必要分頁固定列（不可刪不可移；外觀對齊批次列） */
.settings-tab-fixed {
  margin: var(--space-1) 0;
  padding: 10px 12px;
  border: 1px solid var(--color-text-disabled);
  border-radius: var(--radius-sm);
  font-size: 14px;
}
.batch-row--tab { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-2); min-width: 0; }
.batch-row--tab .field { flex: 1 1 auto; min-width: 0; margin: 0; }
.settings-row__actions { display: flex; gap: 6px; flex: 0 0 auto; padding-bottom: 2px; }
.settings-add { display: flex; flex-wrap: wrap; gap: 8px; margin: var(--space-1) 0; }

/* ---------- 場次登記（階段頁；p157 我要報名，p159、p170 確認對話框） ---------- */
.phase-events { list-style: none; padding: 0; display: grid; gap: var(--space-2); }
.phase-events__item {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-text-disabled);
  border-radius: var(--radius-sm);
  background: #fff;
}
.phase-events__name { font-size: 16px; font-weight: 700; color: var(--color-text-strong); }
.phase-events__time { font-size: 14px; color: var(--color-text-body); margin-top: 2px; }
.phase-events__desc { font-size: 14px; color: var(--color-text-body); margin-top: 6px; }
.phase-reg { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-2); min-height: 36px; }
.phase-reg__btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-width: 120px; height: 36px; padding: 0 20px;
  border: 0; border-radius: var(--radius-sm);
  background: var(--color-primary); color: #fff;
  font-size: 14px; text-decoration: none; cursor: pointer;
}
.phase-reg__btn:hover { filter: brightness(1.05); }
.phase-reg__btn--ghost {
  background: #fff; color: var(--color-text-body);
  border: 1px solid var(--color-text-disabled);
}
.phase-reg__done { font-size: 14px; font-weight: 700; color: var(--color-primary); }
.phase-reg__closed { font-size: 14px; color: var(--color-text-disabled); }
/* 取消報名確認為紅色警示變體（p170：紅頂條搭配紅實心確定鈕） */
.modal--danger { border-top-color: var(--color-danger); }
.modal__btn--danger { background: var(--color-danger); color: #fff; }

/* ---------- QR 簽到（p161/p168–p169 參加方；p153/p163/p165 主辦方名單、掃碼） ---------- */
.phase-qr { display: flex; justify-content: center; margin: var(--space-2) 0; }
.phase-qr svg { width: 180px; height: 180px; }
.phase-qr__hint { font-size: 14px; color: var(--color-text-muted, #939393); margin-bottom: var(--space-2); }
.checkin-picker { margin-bottom: var(--space-3); font-size: 14px; color: var(--color-text-strong); }
/* RWD P3：場次名全文可達 ~490px，原生 select 以最長 option 定寬（375 實測溢出 149px 元凶）。
   flex 搭配 min-width:0 讓 select 對任意長度 label 自動讓位，不靠魔術數字、也無 % max-width 循環依賴 */
.checkin-picker label { display: flex; align-items: center; gap: 8px; }
.checkin-picker select { flex: 0 1 auto; min-width: 0; height: 38px; padding: 0 12px; border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm); font-size: 14px; }
.checkin-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-2); }
.checkin-head__name { font-size: 18px; font-weight: 700; color: var(--color-text-strong); }
.checkin-head__time { font-size: 14px; color: var(--color-text-body); margin-top: 2px; }
.checkin-count { font-size: 15px; font-weight: 700; color: var(--color-text-strong); margin: var(--space-2) 0; }
.checkin-list { list-style: none; padding: 0; display: grid; gap: 10px; }
.checkin-list__item {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px; /* RWD P3：窄幅狀態+按鈕折第二行 */
  padding: 10px var(--space-2);
  background: var(--color-surface, #fff);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-text-disabled);
}
.checkin-list__avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--color-text-disabled); flex-shrink: 0; }
.checkin-list__name { font-size: 15px; font-weight: 700; color: var(--color-text-strong); }
.checkin-list__email { font-size: 14px; color: var(--color-text-body); flex: 1; }
.checkin-list__state { font-size: 14px; font-weight: 700; }
.checkin-list__state--done { color: var(--color-primary); }
.checkin-list__state--pending { color: var(--color-danger); }
.checkin-video { width: 100%; max-height: 280px; border-radius: var(--radius-sm); background: #202020; margin-bottom: var(--space-2); }
.checkin-manual .modal__input { width: 100%; }

/* ---------- 階段繳件（p157 入口、繳件頁、後台繳件名單；一階段一表單）---------- */
.phase-upload-entry { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-1) var(--space-3); margin: var(--space-1) 0 var(--space-2); }
.phase-upload-entry__item { display: inline-flex; align-items: center; gap: 8px; } /* 標籤與按鈕成對，窄螢幕整對換行不拆散、不被壓成直排疊字 */
.phase-upload-entry__label { font-size: 14px; font-weight: 700; color: var(--color-text-strong); white-space: nowrap; }
.phase-files__hint { font-size: 14px; color: var(--color-text-body); } /* PhaseAsk 頁沿用 */
.phase-submission__window { font-size: 14px; color: var(--color-text-body); margin: 0 0 var(--space-2); }
.phase-submission__readonly { font-size: 14px; color: var(--color-text-strong); background: var(--color-surface-alt); border: 1px solid var(--color-border); border-radius: var(--radius-sm); padding: 10px var(--space-2); }
.phase-submissions__export { margin: var(--space-2) 0; }
.phase-submissions__scroll { overflow-x: auto; }
.phase-submissions__table { width: 100%; border-collapse: collapse; margin: var(--space-2) 0; font-size: 14px; }
.phase-submissions__table th { text-align: left; padding: 8px 12px; border-bottom: 1px solid var(--color-border-strong); color: var(--color-text-strong); white-space: nowrap; }
.phase-submissions__table td { padding: 10px 12px; border-bottom: 1px solid var(--color-border); vertical-align: top; }
/* 兩顆 chip 要能換行：中文的「✎ 編輯繳件表單」「⛿ 繳件名單」加起來塞得進窄欄，
   英文的「Edit submission form」「Submission roster」加起來 342px，而容器只有 210px；
   chip 本身是 nowrap，不給 flex-wrap 就會直接衝出視口。 */
.phase-form-links { display: flex; flex-wrap: wrap; gap: var(--space-1); margin: var(--space-1) 0; }

/* =========================================================
   RWD 殼層轉換（docs/design.md「RWD 設計理由與跨檔機制」，D2/D3/D4/D5）
   斷點約定見檔頭。本區統一附掛檔尾：同特異度下後宣告勝出，
   後續 P2/P3 的 media 規則亦接續在此區之後，避免 modifier 宣告序陷阱。
   ========================================================= */

/* ---- 901–1439 帶（D2）：topbar 換行、搜尋框折列 ----
   實測 1024 帶搜尋框的 topbar 溢出 167px（search 有 min-content 不可壓縮）；
   order:3 加上 basis:100% 讓搜尋列固定折到第二列，標題與帳號區同列。≥1440 不受影響 */
@media (max-width: 1439px) {
  .topbar { flex-wrap: wrap; }
  .topbar__search { order: 3; flex-basis: 100%; margin-left: 0; }
  /* 帳號區右對齊原本靠 search 的 flex:1 推擠；search 折走後第一列需自帶推擠力。
     限定「有搜尋框的 topbar」，無搜尋框的 7 處變體不受影響 */
  .topbar__search ~ #account-area { margin-left: auto; }
  /* P2：報名封面 rail 300→240，因為 901–1024 區間內容區僅 ~589px，300px rail 使表單欄剩 257px
     （input 實測 193px＜200 可填性下限）；≥1440 不受影響 */
  .register-layout { grid-template-columns: minmax(0, 1fr) 240px; }
}

/* ---- ≤1024（D2 901–1439 帶內細分）：洞察儀表，以及清單搭配詳情的版型改為單欄（P3） ---- */
@media (max-width: 1024px) {
  .wizard-columns--settings { grid-template-columns: minmax(0, 1fr); }
  /* 5fr/7fr 雙欄下左側統計卡（本身 2 欄格）每卡 <150px、32px 數字溢出 */
  .insight-layout { grid-template-columns: minmax(0, 1fr); }
  /* 單欄帶圖表維持原寬橫捲（等比縮小會讓 10/11px 軸標不可讀）；1025+ 維持既有等比縮放 */
  .insight-chart svg { min-width: 640px; }
  /* 清單搭配詳情的版型：901–1024 內容區 ~589px，340px 名單欄只留 ~217px 詳情（atcc-21 實測溢出 57px），
     故收單欄斷點從 ≤900 提到 ≤1024。minmax(0, 1fr) 不可簡寫成 1fr——後者隱含 min-width:auto，
     詳情裡一段不可折的長值（例如 21 字隊名）會把單欄撐破 375 視口（桌機雙欄規則同款防護） */
  .reg-layout { grid-template-columns: minmax(0, 1fr); }
  .reg-list ul { max-height: 40vh; overflow-y: auto; }
}

/* ---- ≤900：殼層轉換（D3，側欄→頂部品牌條） ---- */
@media (max-width: 900px) {
  .app-shell {
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-2);
  }
  /* 側欄→頂部品牌條的成組覆寫：column 下 flex-basis 變高度、align-self 作用於交叉軸，
     漏一項即炸版；漸層背景保留是為了三主題的視覺色彩識別（藍/青綠/深藍）不丟失 */
  .brand-rail {
    position: relative;        /* 捨 sticky（隨頁捲走）；不可用 static，因為 absolute 的 logo 需要這個錨點 */
    top: 0;                    /* 必覆：基底 top:48px 在 relative 下變成向下位移，會壓到 topbar */
    flex: none;
    align-self: stretch;
    width: 100%;
    height: 72px;
    border-radius: var(--radius-lg);
  }
  .brand-rail__decor { display: none; } /* 直式裝飾（viewBox 315×985 slice）塞橫幅只露底弧，整塊隱藏 */
  .brand-rail__logo {
    top: 50%;
    left: var(--space-3);
    transform: translateY(-50%);
    width: 120px;
  }
  .topbar__title { white-space: normal; }
  .detail-topbar, .register-topbar { flex-wrap: wrap; gap: var(--space-1); }

  /* ---- P2：雙欄版型收單欄（D2 ≤900 帶） ---- */
  /* 活動詳細頁：簡介卡（含報名 CTA）DOM 序在前，收單欄後天然置頂，形成行動裝置的轉換動線 */
  .detail-layout { grid-template-columns: minmax(0, 1fr); }
  /* 報名旅程 6 頁：封面 rail 前置（figma 行動慣例：封面先於表單）。
     實測破版閾值 <768，實施收斂帶依 D2 統一 ≤900 */
  .register-layout { grid-template-columns: minmax(0, 1fr); }
  /* 單欄時右欄變成表單上方的橫幅，黏住只會擋掉一大塊視高，取消桌機的 sticky */
  .register-rail { order: -1; position: static; }
  /* auth 375 溢出 33px 真因：.auth-form 固定 360px 使 grid item min-content=408px（min-width:auto），
     放行收縮後內層 max-width:100% 才會生效 */
  /* 單欄（hero 已隱藏）不再垂直置中：置中會把表單推到畫面中段，而 footer 連結（註冊、忘記密碼）
     釘在 100vh 的底——手機瀏覽器的網址列吃掉視高後，這兩條就落到可視範圍外，得下捲才找得到。
     改直欄排版：表單靠上、footer 緊跟表單之後，登入資訊與後續動線同屏可見 */
  .auth-side { min-width: 0; flex-direction: column; justify-content: flex-start; align-items: center; padding-bottom: var(--space-4); }
  .auth-side__footer { position: static; margin-top: var(--space-5); }

  /* ---- P3：主辦方後台雙欄收單欄（D2 ≤900 帶；reg-layout 已提前到 ≤1024 帶） ---- */
  /* 建立精靈/設定與發布雙欄；--settings 變體（5fr/7fr）特異度同級，必須同塊一併覆寫 */
  .wizard-columns, .wizard-columns--settings { grid-template-columns: minmax(0, 1fr); }
  /* 洞察橫幅 gap 48 收斂（P0 只補 wrap；gap 改值屬桌機可見故入 media） */
  .insight-banner { gap: var(--space-2) var(--space-4); }

  /* 後台標題預留右側空間，避免長標題（如「…全國大專院校商業大賽」）被右上絕對定位的帳號區（鈴鐺與頭像）蓋住 */
  .app-shell--host .register-title { padding-right: 160px; }
}

/* ---- ≤768：資訊降級（D5c） ---- */
@media (max-width: 768px) {
  .content-panel__illustration { display: none; } /* 純裝飾插圖，窄幅蓋內容 */
  /* 後台兩排分頁 → 原生下拉選單：窄螢幕不再靠橫向捲動找後段分頁 */
  .page-tabs--backend, .page-tabs--content-edit { display: none; }
  .backend-nav-select { display: flex; align-items: center; gap: 8px; margin-top: var(--space-2); }
}

/* ---- ≤600：手機細節 ---- */
@media (max-width: 600px) {
  .content-panel { padding: var(--space-2); border-radius: var(--radius-md); }
  .account-area__name { display: none; } /* D5a：只留頭像識別登入態 */
  /* 帳號區於 ≤600 只剩鈴鐺與頭像，標題預留空間縮小即可 */
  .app-shell--host .register-title { padding-right: 96px; }
  /* 設定/表格頁底部操作列：窄螢幕改整排堆疊，避免「⌫ 刪除活動」被擠到折行 */
  .forms-actions .action-btn { flex-basis: 100%; }
  .modal { padding: var(--space-3) var(--space-2) var(--space-2); }
  .modal__field select, .modal__input { width: 100%; } /* 窄對話框內 70% 太擠 */

  /* ---- stepper 兩條分治：等分規則與階段列橫捲互斥（flex:1 1 0 會讓橫捲永不觸發），不可合併 ---- */
  /* 報名 3–4 步：等分收縮（連接線 right:calc(50%+18px) 相對 item 自身，等寬下自適應） */
  .register-steps__item { flex: 1 1 0; width: auto; min-width: 0; }
  /* 階段列（橫捲已無條件生效於基底區）：等分規則的 width:auto/min-width:0 需在此覆寫回 */
  .phase-steps .register-steps__item { flex: 0 0 auto; width: auto; min-width: 72px; }

  /* ---- P3：建立精靈步驟列與洞察橫幅手機細節 ---- */
  .wizard-steps { gap: 4px; }
  .wizard-steps__item:not(:last-child)::after { width: 20px; } /* 連接線 56→20 */
  /* 四步 label 共 23 個 CJK 字（~299px）在 375 數學上塞不進，因此非 active 只留編號 dot（常見手機 stepper 收斂） */
  .wizard-steps__item:not(.wizard-steps__item--active) .wizard-steps__label { display: none; }
  .insight-banner { padding: var(--space-2); font-size: 15px; }
  /* 統計卡 2 欄格內寬 ~107px，五位數（12,345 人）會溢卡，故收為 1 欄（六卡直疊不長） */
  .insight-cards { grid-template-columns: minmax(0, 1fr); }
  /* 分組與報名名單的標題列：窄螢幕標題（如「報名隊伍 共 0 組」）與 170px 搜尋框並排會被擠到折行斷字，改標題在上、搜尋框在下整寬堆疊 */
  .reg-list__head { flex-direction: column; align-items: stretch; }
  .reg-list__head input { width: 100%; }
}

/* ---- ≤480：手機窄幅細節（P2） ---- */
@media (max-width: 480px) {
  .timeline__item { --timeline-when-w: 88px; } /* 豎線隨變數同步 */
  .timeline__date { font-size: 15px; }
  .comment--reply, .comment-form--reply { margin-left: var(--space-3); } /* 縮排 56→24，保留層級視覺 */
  .comment-form__name { display: none; } /* D5b：頭像已足以識別發言者 */
  .auth-side { padding: var(--space-4) var(--space-2); } /* footer 於 ≤900 帶已改常流排版，無需再預留絕對定位空間 */
  /* 簽到「場次」選單：窄螢幕左側標籤欄過窄會把「場次」壓成直排，改標籤置於 select 上方 */
  .checkin-picker label { flex-direction: column; align-items: stretch; gap: 4px; }
}

/* 開辦進度卡（活動洞察頁頂端；正式公開且必要項目完成後預設收合）。
   狀態不只靠顏色：每一列都有文字狀態，符號只是輔助。 */
.setup-card {
  border: 1px solid var(--color-border, #D9D9D9);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-3);
  background: var(--color-surface);
}
.setup-card__summary { font-size: 16px; font-weight: 700; color: var(--color-text-strong); cursor: pointer; }
.setup-card__state { margin-left: 8px; font-size: 13px; font-weight: 400; color: var(--color-text-muted); }
.setup-card__heading { margin: var(--space-2) 0 6px; font-size: 13px; color: var(--color-text-muted); }
.setup-card__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.setup-card__item { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.setup-card__mark { width: 1.2em; text-align: center; color: var(--color-text-muted); }
.setup-card__item--done .setup-card__mark { color: var(--color-status-open); }
/* 已完成的項目退到背景：清單依編輯動線排序、不依完成與否重排（順序本身是指引），
   於是完成與未完成交錯出現，一眼掃過去分不出還缺什麼。把已完成那幾列的連結降成次要灰，
   未完成的維持藍色連結色，待辦就自己浮出來了。狀態文字本來就在，不是只靠顏色分辨。 */
.setup-card__item--done a { color: var(--color-text-muted); }
.setup-card__item--needscheck .setup-card__mark { color: var(--color-status-closing); }
.setup-card__status { font-size: 12px; color: var(--color-text-muted); }
.setup-card__foot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: var(--space-2); font-size: 13px; color: var(--color-text-body); }

/* 後台右上帳號區（設計稿 p129–133）：絕對定位於 host app-main 右上；
   position 情境限縮在 host 主題，不影響其他頁面既有定位。htmx 只換內層 #account-area，
   外層 .backend-account 保留定位。 */
.app-shell--host .app-main { position: relative; }
.backend-account { position: absolute; top: 16px; right: 0; z-index: 5; display: flex; align-items: center; gap: var(--space-2); }
/* 公開頁預覽入口與可見性提示：與帳號區同列右上，窄螢幕收成單欄並讓提示換行 */
.backend-preview { display: flex; align-items: center; gap: 8px; }
.backend-preview .field__hint { max-width: 22em; }
@media (max-width: 900px) {
  .backend-account { position: static; flex-direction: column; align-items: flex-end; gap: 6px; margin-bottom: var(--space-2); }
  .backend-preview { flex-wrap: wrap; justify-content: flex-end; }
  .backend-preview .field__hint { text-align: right; }
}

/* ---------- 協作與權限分頁（PDF p129–131；docs/specs/collaboration-and-permissions.md） ---------- */
.collab-role { margin: var(--space-2) 0 var(--space-3); }
.collab-role__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; margin-bottom: 10px; }
.collab-role__head strong { font-size: 15px; color: var(--color-text-strong); }
.collab-role__hint { font-size: 13px; color: var(--color-text-body); }
.collab-cards { display: flex; flex-wrap: wrap; gap: var(--space-2); border-top: 1px solid #eee; padding-top: var(--space-2); }
.collab-card {
  display: flex; align-items: center; gap: 10px;
  min-width: 230px; padding: 10px 12px;
  background: #fff; border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm);
}
.collab-card--owner { background: #F6FBFE; }
.collab-card__avatar { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; background: #D9D9D9; }
.collab-card__body { display: flex; flex-direction: column; min-width: 0; }
.collab-card__name { font-size: 14px; color: var(--color-text-strong); display: flex; align-items: center; gap: 6px; }
.collab-card__email { font-size: 12px; color: var(--color-text-body); }
.collab-card__groups { font-size: 12px; color: var(--color-text-body); margin-top: 2px; }
.collab-card__pending { font-size: 11px; color: var(--color-accent, #FFB321); border: 1px solid var(--color-accent, #FFB321); border-radius: 999px; padding: 0 6px; }
.collab-card__remove-form { margin-left: auto; }
.collab-card__remove { border: none; background: none; color: var(--color-text-disabled); font-size: 15px; cursor: pointer; line-height: 1; }
.collab-card__remove:hover { color: var(--color-danger); }
.collab-add {
  display: inline-flex; align-items: center; min-width: 150px; justify-content: center;
  padding: 10px 12px; border: 1px dashed var(--color-text-disabled); border-radius: var(--radius-sm);
  background: #FAFAFA; color: var(--color-text-body); font-size: 14px; cursor: pointer;
}
.collab-add:hover { border-color: var(--color-primary); color: var(--color-primary); }
.collab-groups { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.collab-groups__item { font-size: 14px; color: var(--color-text-strong); display: flex; align-items: center; gap: 8px; }
.collab-notify { display: flex; align-items: center; gap: 8px; justify-content: center; font-size: 14px; color: var(--color-text-strong); margin-top: var(--space-2); }

/* ---------- 評分（PDF p90–91；docs/specs/judging.md） ---------- */
.scoring-toggle { display: inline-flex; align-items: center; gap: 8px; }
.scoring-toggle__label { font-size: 14px; color: var(--color-text-strong); }
.scoring-toggle__btn { width: 46px; height: 26px; border: none; border-radius: 999px; background: var(--color-text-disabled); position: relative; cursor: pointer; padding: 0; }
.scoring-toggle__btn--on { background: var(--color-primary); }
.scoring-toggle__knob { position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: #fff; transition: left .15s; }
.scoring-toggle__btn--on .scoring-toggle__knob { left: 23px; }
.scoring-status { font-size: 13px; color: var(--color-text-body); white-space: nowrap; }
.reg-list__score { font-size: 12px; color: var(--color-text-disabled); margin-left: auto; }
.reg-list__score--done { color: var(--color-primary); font-weight: 700; }
.score-summary { margin: var(--space-2) 0; padding: var(--space-2); background: #F6FBFE; border-radius: var(--radius-sm); }
.score-summary__avg { font-size: 15px; font-weight: 700; color: var(--color-text-strong); }
.score-summary__round { font-size: 13px; color: var(--color-text-body); }
.score-summary__judges { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 6px; }
.score-summary__judge { font-size: 13px; color: var(--color-text-body); }
.score-summary__judge--self { color: var(--color-primary); font-weight: 700; }
.score-dialog__team { font-size: 16px; font-weight: 700; color: var(--color-text-strong); text-align: center; margin: 4px 0 var(--space-2); }
.score-dialog__board { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 16px; font-size: 13px; color: var(--color-text-body); margin-bottom: var(--space-2); }
.score-dialog__inputs { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: center; }
.score-dialog__item { display: flex; flex-direction: column; gap: 4px; font-size: 14px; color: var(--color-text-strong); }
.score-dialog__item input { width: 130px; height: 38px; padding: 0 12px; border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm); text-align: center; }
.score-dialog__note { display: block; margin-top: var(--space-2); font-size: 14px; color: var(--color-text-strong); }
.score-dialog__note textarea { display: block; width: 100%; min-height: 70px; margin-top: 6px; padding: 8px 12px; border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm); font: inherit; }

/* ---------- 問卷調查（PDF p101–102；docs/specs/surveys.md） ---------- */
.survey-list { list-style: none; margin: var(--space-2) 0; padding: 0; }
.survey-list__item { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; padding: 10px 0; border-bottom: 1px solid #eee; }
.survey-list__name { font-size: 15px; color: var(--color-text-strong); font-weight: 700; }
.survey-list__loc { font-size: 12px; color: var(--color-text-body); border: 1px solid var(--color-text-disabled); border-radius: 999px; padding: 1px 8px; }
.survey-list__url { flex-basis: 100%; font-size: 13px; color: var(--color-primary); word-break: break-all; }
.survey-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 8px 0; border-bottom: 1px dashed #eee; }
.survey-row > label { font-size: 13px; color: var(--color-text-strong); min-width: 48px; }
.survey-row input, .survey-row select { height: 36px; padding: 0 10px; border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm); font: inherit; }
.survey-row input[name$='.Name'] { flex: 1 1 140px; }
.survey-row input[name$='.Url'] { flex: 2 1 220px; }
/* 學生端：插入位置呈現的問卷連結區塊 */
.survey-embed { margin: var(--space-2) 0; padding: var(--space-2); background: var(--color-surface-alt, #F6FBFE); border-radius: var(--radius-sm); }
.survey-embed__title { font-size: 14px; font-weight: 700; color: var(--color-text-strong); margin-bottom: 6px; }
.survey-embed__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.survey-embed__link { font-size: 14px; color: var(--color-primary); }

/* 登入頁「保持登入」 */
.afield-remember { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--color-text-body); margin: 4px 0 10px; }

/* ---- 語系切換器：固定右下角浮動小元件——不佔文流、不動殼層 rect，
   全站兩個 layout 各掛一次即覆蓋；語系為 OutputCache 快取鍵維度，可安全渲染進快取頁 ---- */
/* 半透明待機：固定浮鈕會壓在捲到底的內容右下角（活動卡的「活動詳情」鈕曾被整顆蓋住），
   待機時退為半透明、指標靠近才全顯；body 另在 _Layout 預留底部空間讓最後一列內容捲得出來 */
.culture-switcher { position: fixed; right: 10px; bottom: 10px; z-index: 60; display: flex; gap: 4px; opacity: .55; transition: opacity .15s; }
.culture-switcher:hover, .culture-switcher:focus-within { opacity: 1; }
/* 沒有 hover 能力的裝置上，那條「淡出等 hover」的規則永遠等不到：切換鈕會一直停在 55%
   不透明度，12px 的小字讀起來很吃力，而它是換語言的唯一入口。手指裝置直接給全不透明。 */
@media (hover: none) {
  .culture-switcher { opacity: 1; }
}
.culture-switcher form { margin: 0; }
.culture-switcher__btn {
  min-width: 40px; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--color-border, #D9D9D9);
  background: rgba(255, 255, 255, .92); color: var(--color-text-muted, #606060);
  font-size: 12px; line-height: 1.6; cursor: pointer;
}
.culture-switcher__btn--active { border-color: var(--color-primary, #05C3F7); color: var(--color-primary, #05C3F7); font-weight: 700; }

/* 平台補登表單（/admin/records；延伸自 admin-role-form 版式） */
.record-admin-form { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: flex-end; margin: var(--space-2) 0 var(--space-3); }
.record-admin-form label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--color-text-strong); }
.record-admin-form input, .record-admin-form select { height: 36px; padding: 0 10px; border: 1px solid var(--color-text-disabled); border-radius: var(--radius-sm); font: inherit; min-width: 150px; }
/* 空狀態列：置中的次要文字，與資料列明顯不同，不會被誤讀成一筆內容 */
.admin-table__empty { text-align: center; color: var(--color-text-muted); }
.admin-table__actions { display: flex; gap: 6px; align-items: center; }
.admin-table__actions form { margin: 0; }
