/* ---------- 主題 ---------- */
:root {
  --bg: #fbfaf8;
  --panel: #ffffff;
  --border: #e3ded6;
  --text: #23201c;
  --muted: #7d766c;
  --chord: #c2410c;
  --accent: #1d6f5c;
  --role-m: #1d4ed8;
  --role-f: #be185d;
  --role-b: #15803d;   /* 合：習慣上是綠色 */
  --role-t: #6d28d9;   /* 團：接手原本合的紫色，跟綠色的合分得開 */
  /* 分組：同一段和弦唱兩三次時，第幾次用第幾個顏色。
     刻意避開上面四個聲部色，才不會跟男女合團混在一起。 */
  --grp-1: #b45309;
  --grp-2: #0e7490;
  --grp-3: #a21caf;
  --grp-4: #4d7c0f;
  --shadow: 0 1px 2px rgba(0, 0, 0, .05), 0 8px 24px rgba(0, 0, 0, .04);
  --radius: 10px;
  --sheet-size: 18px;
}

:root[data-theme="dark"] {
  --bg: #17161a;
  --panel: #1f1e23;
  --border: #34323a;
  --text: #eceaf0;
  --muted: #9a95a3;
  --chord: #fb923c;
  --accent: #5eead4;
  --role-m: #7dabff;
  --role-f: #f9a8d4;
  --role-b: #86efac;
  /* 不能用 #5eead4 —— 那跟深色模式的 --accent 一模一樣，標籤會跟按鈕混在一起 */
  --role-t: #c4b5fd;
  --grp-1: #fbbf24;
  --grp-2: #67e8f9;
  --grp-3: #f0abfc;
  --grp-4: #bef264;
  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 24px rgba(0, 0, 0, .3);
}

* { box-sizing: border-box; }

/* hidden 屬性是靠瀏覽器預設樣式的 display:none 生效，
   只要自己在某個 class 上寫了 display（例如 display:flex），
   作者樣式就會蓋掉它 —— 元素明明 hidden=true 卻照樣佔著位置。
   .member-bar 就是這樣變成一條空的綠色長條。整站統一擋掉這個坑。 */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", system-ui, -apple-system, sans-serif;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}

a { color: inherit; }

/* ---------- 版面 ---------- */
.wrap { max-width: 900px; margin: 0 auto; padding: 0 16px 96px; }
/* 編輯頁是表單＋預覽兩欄，用看譜頁的窄版會擠成一團、兩側大片留白 */
body[data-view="editor"] .wrap { max-width: 1500px; }

.topbar {
  position: sticky; top: 0; z-index: 30;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}
.topbar-inner {
  max-width: 900px; margin: 0 auto; padding: 10px 16px;
  display: flex; align-items: center; gap: 12px;
}
/* 標誌：C 和弦指板圖 + PoYou 譜友。線條用 --accent、點用 --chord，深色模式跟著換色 */
.brand {
  display: inline-flex; align-items: center; gap: 8px; flex: none;
  font-weight: 900; font-size: 17px; text-decoration: none; letter-spacing: .03em;
}
.brand-mark { width: 24px; height: 28px; flex: none; margin-right: 2px; }
.brand-zh { margin-left: -3px; }
.brand-mark line { stroke: var(--accent); stroke-width: 1.3; }
.brand-mark .bm-nut { fill: var(--accent); }
.brand-mark .bm-dot { fill: var(--chord); }
.brand-zh { color: var(--accent); }
.nav-yt button { display: inline-flex; align-items: center; gap: 6px; }
.nav-yt svg { width: 16px; height: 16px; }
.nav-yt rect { fill: none; stroke: currentColor; stroke-width: 1.5; }
.nav-yt path { fill: currentColor; }
/* 手機導覽列放不下全部的字：英文名與「YouTube」字樣收起來，只留圖 */
@media (max-width: 480px) {
  .topbar-inner { gap: 8px; }
  .brand-en, .nav-yt span { display: none; }
}
.topbar .spacer { flex: 1; }

.login-pane { max-width: 380px; margin: 48px auto; }
.login-pane h2 { margin: 0 0 16px; font-size: 16px; }
.login-pane input { width: 100%; }

.draft-banner {
  background: color-mix(in srgb, var(--chord) 12%, var(--bg));
  border-bottom: 1px solid var(--border);
  color: var(--chord);
  font-size: 13px;
  padding: 7px 16px;
  text-align: center;
}

/* ---------- 控制元件 ---------- */
button, select, input, textarea {
  font: inherit; color: inherit;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 10px;
}
button { cursor: pointer; }
button:hover { border-color: var(--accent); }
button.primary { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
:root[data-theme="dark"] button.primary { color: #10201c; }
button.ghost { background: transparent; }
button.on { background: var(--accent); border-color: var(--accent); color: #fff; }
:root[data-theme="dark"] button.on { color: #10201c; }
button.icon { padding: 6px 9px; line-height: 1; }
textarea { width: 100%; resize: vertical; }

.field { display: flex; flex-direction: column; gap: 4px; }
.field label { font-size: 12px; color: var(--muted); }

/* ---------- 歌曲列表 ---------- */
.search-row { display: flex; gap: 8px; margin: 20px 0 8px; }
.search-row input { flex: 1; }
.count { color: var(--muted); font-size: 13px; margin: 0 0 12px; }

.song-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
/* 換行：手機上歌名、歌手、製譜人、調性排不進同一行，
   不讓它換行的話字會被擠成一直很難看 */
.song-list a {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px;
  padding: 12px 14px; text-decoration: none;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius);
}
.song-list a:hover { border-color: var(--accent); }
.song-list .t { font-weight: 600; }
.song-list .a { color: var(--muted); font-size: 14px; }
/* 製譜人比歌手次要，再小一號 */
.song-list .by { color: var(--muted); font-size: 12px; }
.song-list .g {
  font-size: 11px; font-weight: 700; line-height: 1.5;
  padding: 0 .4em; border-radius: 4px; border: 1px solid currentColor;
}
.song-list .g.role-m { color: var(--role-m); }
.song-list .g.role-f { color: var(--role-f); }
.song-list .g.role-b { color: var(--role-b); }
.song-list .g.role-t { color: var(--role-t); }

.song-list a.unpublished { opacity: .55; border-style: dashed; }
.song-list .g.down { color: var(--muted); }
/* 語言用淡一點的顏色：一列裡性別才是主角，兩個都淡強調就全部看不見 */
.song-list .g.lang { color: var(--muted); font-weight: 600; }

.filter-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.filter-row select { max-width: 100%; }
.song-list .k { margin-left: auto; color: var(--chord); font-size: 13px; font-weight: 600; white-space: nowrap; }
.empty { color: var(--muted); padding: 40px 0; text-align: center; }

/* ---------- 看譜工具列 ---------- */
.song-head { padding: 18px 0 4px; }
.song-head h1 { margin: 0 0 4px; font-size: 24px; }
.song-head .meta { color: var(--muted); font-size: 14px; display: flex; flex-wrap: wrap; gap: 4px 14px; }

.toolbar {
  position: sticky; top: 49px; z-index: 20;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
  margin: 12px -16px 0; padding: 10px 16px;
  display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center;
}
.tool-extra { display: contents; }
.more-btn { display: none; }
.tool { display: flex; align-items: center; gap: 6px; }
.tool > .lbl { font-size: 12px; color: var(--muted); }
/* 連在一起的一組控制項。原本 −、數值、＋ 各自有框，看起來像三個不相干的東西，
   分不出哪顆按鈕在調哪個數值。併成一格分隔線相連的群組就有從屬關係了。 */
.group {
  display: inline-flex; align-items: stretch;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--panel); overflow: hidden;
}
.group > * {
  border: none; border-radius: 0; background: transparent;
  margin: 0; display: flex; align-items: center;
}
.group > * + * { border-left: 1px solid var(--border); }
/* 每一格都給一樣的最小尺寸。原本高度由各自的字級決定，
   速度那組因為用 11px 小字，按鈕只有 27x28，手機上很難按準。 */
.group > * { min-height: 34px; }
.group button { min-width: 40px; justify-content: center; }
.group button:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.group button:active { background: color-mix(in srgb, var(--accent) 22%, transparent); }

.keybox {
  min-width: 58px; text-align: center; justify-content: center;
  font-weight: 700; color: var(--chord); padding: 4px 8px;
}
.sound-hint { font-size: 12px; color: var(--muted); white-space: nowrap; }
.speed-out { font-size: 11px; color: var(--muted); min-width: 4.4rem; padding: 0 4px;
  justify-content: center; text-align: center; white-space: nowrap; }

.hint { font-size: 12px; color: var(--muted); }
.hint b { color: var(--chord); }

/* ---------- 譜面 ---------- */
.sheet { font-size: var(--sheet-size); padding: 20px 0 40px; }
.sheet .blank { height: .8em; }
.sheet .section {
  margin: 22px 0 8px; font-size: .82em; letter-spacing: .08em;
  color: var(--accent); text-transform: uppercase;
  border-bottom: 1px solid var(--border); padding-bottom: 4px;
}
.sheet .note { margin: 6px 0; font-size: .82em; color: var(--muted); }
/* 區域：重複的段落只寫一次，左邊一條線標出範圍。
   只有收合時才畫 —— 展開時內容都寫出來了，加框反而讓人以為是別的一段。 */
.sheet .area-box {
  border-left: 3px solid var(--accent);
  padding-left: .7em; margin: 10px 0;
}
.sheet .area-tag {
  font-size: .7em; font-weight: 700; letter-spacing: .06em;
  color: var(--accent); margin-bottom: 2px;
}
/* 收合時的那一行 */
.sheet .area-use-line {
  margin: 14px 0 10px; font-size: .8em; font-weight: 700;
  color: var(--accent);
  display: flex; align-items: center; gap: .6em;
}
.sheet .area-use-line::after {
  content: ''; flex: 1; height: 0;
  border-top: 1px dashed currentColor; opacity: .5;
}
/* 呼叫了不存在的區域：要看得出來是寫錯了，不是正常顯示 */
.sheet .area-use-line.missing { color: var(--chord); }

.line {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  margin-bottom: .45em; min-height: 1.2em;
}
.line.dimmed { opacity: .35; }
.seg-tag .tx { display: flex; align-items: center; }
.role-tag {
  font-size: .6em; font-weight: 700; line-height: 1.5;
  padding: 0 .45em; border-radius: 4px;
  border: 1px solid currentColor;
}
.seg-tag { margin-right: .5em; }
.role-tag.role-m { color: var(--role-m); }
.role-tag.role-f { color: var(--role-f); }
.role-tag.role-b { color: var(--role-b); }
.role-tag.role-t { color: var(--role-t); }
.role-tag.role-g1 { color: var(--grp-1); }
.role-tag.role-g2 { color: var(--grp-2); }
.role-tag.role-g3 { color: var(--grp-3); }
.role-tag.role-g4 { color: var(--grp-4); }
/* 聲部是每段各自的，同一行可以男女對唱 */
.seg.role-m .tx { color: var(--role-m); }
.seg.role-f .tx { color: var(--role-f); }
.seg.role-b .tx { color: var(--role-b); }
.seg.role-t .tx { color: var(--role-t); }
.seg.role-g1 .tx { color: var(--grp-1); }
.seg.role-g2 .tx { color: var(--grp-2); }
.seg.role-g3 .tx { color: var(--grp-3); }
.seg.role-g4 .tx { color: var(--grp-4); }

.seg { display: flex; flex-direction: column; }
.seg .ch {
  color: var(--chord); font-weight: 700;
  font-size: .78em; line-height: 1.35;
  white-space: pre; padding-right: .5em;
  font-family: "SF Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
}

/* 插音（走音）：和弦後面那一小串簡譜數字（[G 1753]）。
   比和弦小一點、淡一點，才不會跟和弦名搶。高低八度的點用 CSS 疊上去，不佔字寬。 */
.ch-fill { margin-left: .3em; font-size: .8em; font-weight: 600; color: var(--muted); letter-spacing: .06em; }
.ch-fill-acc { font-size: .85em; vertical-align: .15em; }
/* 高低八度的點：對準數字本身（所以掛在數字那個 span 上，不是整個「♯6」），
   兩個八度時**直排**兩點（跟簡譜區塊一樣），不是橫排 —— 橫排會被看成兩個音各一點。
   ::before 是靠近數字的那一點，::after 是外側那一點。 */
.ch-fill-num { position: relative; }
.ch-fill-num::before,
.ch-fill-num::after {
  position: absolute; left: 50%; transform: translateX(-50%); line-height: 1;
}
.ch-fill-num.hi::before,
.ch-fill-num.hi2::before { content: '·'; top: -.62em; }
.ch-fill-num.hi2::after { content: '·'; top: -1.02em; bottom: auto; }
.ch-fill-num.lo::after,
.ch-fill-num.lo2::after { content: '·'; bottom: -.52em; }
.ch-fill-num.lo2::before { content: '·'; bottom: -.92em; top: auto; }
/* 行高與最小高度必須是同一個值。
   之前 min-height 用 1.4em、實際行高卻是 1.5em，空的那段就比有字的矮 1.8px，
   flex-end 對齊時行尾「只有和弦」的那段就掉下去了。 */
.seg .tx { white-space: pre-wrap; line-height: 1.5; min-height: 1.5em; }
.line.no-lyrics .tx { display: none; }

/* 簡譜高低音的點。絕對定位，不佔行高，才不會把和弦與歌詞的對齊推歪 */
.jp { position: relative; }
.jp-dot {
  position: absolute; left: 50%;
  width: .16em; height: .16em; border-radius: 50%;
  background: currentColor;
}
.jp-hi .jp-dot { top: calc(0.1em - var(--i) * 0.24em); transform: translateX(-50%); }
.jp-lo .jp-dot { bottom: calc(-0.14em - var(--i) * 0.24em); transform: translateX(-50%); }
/* 高音最多兩點：第二點最高只到數字上方 0.14em，留 0.3em 就夠，
   再多就變成和弦離歌詞太遠。padding 要一起算進 min-height（全站是 border-box），
   否則行尾「只有和弦」那段會比別人矮而掉下去。 */
.line.has-jp .tx {
  padding-top: .3em; padding-bottom: .35em;
  min-height: calc(1.5em + .65em);
}

.sheet.hide-chords .ch { display: none; }
.sheet.hide-lyrics .tx { display: none; }
.sheet.hide-lyrics .seg .ch { padding-right: .8em; }

/* 六線譜 */
.tab-wrap { margin: 12px 0; overflow-x: auto; }
.tab { display: block; max-width: 100%; height: auto; }
/* 照小節線切成一段一段，排不下就整小節換到下一行（跟簡譜一樣），數字才不會被整張縮小。
   左邊的 padding 是給弦名的空間，寬度由 render.js 用 em 給。 */
.tab-lines { display: flex; flex-wrap: wrap; align-items: flex-start; row-gap: .35em; }
.tab-seg { position: relative; flex: 0 1 auto; min-width: 0; max-width: 100%; }
/* 和弦名比一小節長時可以超出去一點，不要被切掉 */
.tab-seg > .tab { overflow: visible; }
/* 弦名疊在左邊預留的空間，不佔版面；只有每一行的第一小節顯示 */
.tab-labels { position: absolute; top: 0; height: auto; display: none; overflow: visible; }
.tab-seg.line-start > .tab-labels { display: block; }
/* 列印時版面寬度不一樣，螢幕上算的行首不準：只在整段開頭放弦名 */
@media print {
  .tab-seg > .tab-labels { display: none; }
  .tab-seg:first-child > .tab-labels { display: block; }
}
.tab-string { stroke: var(--border); stroke-width: 1; }
.tab-bar { stroke: var(--muted); stroke-width: 1.2; }
.tab-bg { fill: var(--bg); }
.tab-label { fill: var(--muted); font-size: 9px; font-family: ui-monospace, Consolas, monospace; }
.tab-fret {
  fill: var(--text); font-size: 11px; font-weight: 700;
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
}
.tab-fret.bad { fill: var(--chord); }
/* 跟彈唱那邊的和弦一樣大。
   .seg .ch 是 .78em、譜面預設 18px → 14px。
   這裡不能寫 .78em：整張 SVG 已經照字級縮放了，再用 em 會放大兩次。
   （render.js 的 TAB_BASE 就是那個 18） */
.tab-chord {
  fill: var(--chord); font-size: 14px; font-weight: 700;
  font-family: "SF Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
}
.tab-head { fill: var(--text); }
.tab-head.hollow { fill: var(--bg); stroke: var(--text); stroke-width: 1; }
.tab-stem { stroke: var(--text); stroke-width: 1; }
.tab-beam { stroke: var(--text); stroke-width: 2; stroke-linecap: butt; }
/* 附點。小歸小，不能淡——看不到就等於拍子讀錯 */
.tab-dot { fill: var(--text); }
/* 連結線。不填色，否則弧線底下會被塊狀的顏色蓋掉 */
.tab-tie { fill: none; stroke: var(--text); stroke-width: 1.2; }
.tab-wrap figcaption { font-size: .75em; color: var(--muted); margin-top: 2px; }
.tab-locked {
  margin: 0; font-size: .78em; color: var(--muted);
  border-left: 3px solid var(--border); padding: 2px 0 2px 10px;
}

.sheet-img { margin: 14px 0; }
.sheet-img img {
  max-width: 100%; border: 1px solid var(--border);
  border-radius: var(--radius); background: #fff;
}
.sheet-img figcaption { font-size: .78em; color: var(--muted); margin-top: 4px; }
/* TAB 圖多半是白底，深色模式下調暗一點才不刺眼，但要維持看得清楚 */
:root[data-theme="dark"] .sheet-img img { filter: brightness(.88); }

/* ---------- 左右兩欄 ---------- */
/* 直向螢幕每一欄都窄到會把歌詞折斷，兩欄沒有意義，連按鈕都不要出現 */
@media (orientation: portrait) {
  .toolbar .two-col-tool { display: none; }
}
@media (orientation: landscape) {
  /* 譜面平常刻意做窄（歌詞行拉太長不好讀），分成兩欄時要放寬，
     否則每一欄只剩四百多 px，一句歌詞會被折成兩三行。 */
  body[data-cols="2"] .wrap { max-width: 1500px; }
  body[data-cols="2"] .sheet {
    column-count: 2; column-gap: 40px;
    column-rule: 1px solid var(--border);
  }
  /* 一行的和弦與歌詞是上下疊起來對齊的，被切到另一欄去就對不起來了。
     六線譜與簡譜的每一小節同理，切一半會看不懂。 */
  body[data-cols="2"] .sheet .line,
  body[data-cols="2"] .sheet .tab-wrap,
  body[data-cols="2"] .sheet .jp-grid,
  body[data-cols="2"] .sheet .sheet-img { break-inside: avoid; }
  /* 段落標題落在欄尾、內容跑到下一欄，看起來像少了一段 */
  body[data-cols="2"] .sheet .section { break-after: avoid; }
}

.chord-summary {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  padding: 12px 0; border-top: 1px dashed var(--border); margin-top: 8px;
}
.chord-summary .lbl { font-size: 12px; color: var(--muted); margin-right: 4px; }
.chord-summary .c {
  font-weight: 700; color: var(--chord); font-size: 14px;
  padding: 3px 8px; border: 1px solid var(--border); border-radius: 6px; background: var(--panel);
}

/* ---------- 編輯器 ---------- */
.editor-grid { display: grid; gap: 16px; grid-template-columns: 1fr; margin-top: 16px; }
@media (min-width: 860px) { .editor-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1300px) { .editor-grid { gap: 24px; } .preview { max-height: 72vh; } }
/* 兩欄時預覽這一欄撑滿整個視窗高，而且跟著捲軸黏在畫面上。
   之前只有 .preview 限定 max-height（視窗的 6~7 成），左邊表單一長，
   右邊這一欄就被 grid 拉長、下面空一大塊沒用到。
   top 要让過頂端的導覽列（它也是 sticky）。 */
@media (min-width: 860px) {
  .editor-grid { align-items: start; }
  .preview-pane {
    position: sticky; top: calc(var(--topbar-h, 58px) + 12px);
    height: calc(100vh - var(--topbar-h, 58px) - 24px);
    height: calc(100dvh - var(--topbar-h, 58px) - 24px);
    display: flex; flex-direction: column;
  }
  .preview-pane .preview { flex: 1; min-height: 0; max-height: none; }
}
.pane {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 14px; box-shadow: var(--shadow);
}
.pane h2 { margin: 0 0 12px; font-size: 15px; }

.chord-row { gap: 5px; }
.chord-btn {
  padding: 4px 9px; font-size: 13px; font-weight: 700;
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  color: var(--muted);
}
/* 這首用過的排前面也標出來，打譜時最常按的就是這些 */
.role-btn { font-weight: 700; }
.role-btn.m { color: var(--role-m); }
.role-btn.f { color: var(--role-f); }
.role-btn.b { color: var(--role-b); }
.role-btn.g1 { color: var(--grp-1); }
.role-btn.g2 { color: var(--grp-2); }
.role-btn.g3 { color: var(--grp-3); }
.role-btn.g4 { color: var(--grp-4); }

.chord-btn.used { color: var(--chord); border-color: color-mix(in srgb, var(--chord) 35%, var(--border)); }

/* 編輯器的狀態標籤。貼在分頁列右邊，一眼就知道這首發出去了沒 */
.status-tag {
  margin-left: auto; align-self: center;
  font-size: 12px; font-weight: 700; line-height: 1.6;
  padding: 0 .6em; border-radius: 999px; border: 1px solid currentColor;
}
.status-tag.st-draft { color: var(--muted); }
.status-tag.st-live { color: var(--role-b); }
.status-tag.st-off { color: var(--chord); }
/* 刪除這種救不回來的動作要看起來就不一樣 */
button.ghost.danger { color: var(--chord); border-color: var(--chord); }
button.ghost.danger:disabled { opacity: .45; }

.tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--border); }
.tabs .tab {
  border: none; border-bottom: 2px solid transparent; border-radius: 0;
  padding: 8px 14px; font-size: 14px; color: var(--muted); background: transparent;
}
.tabs .tab:hover { color: var(--text); }
.tabs .tab.on {
  color: var(--accent); border-bottom-color: var(--accent);
  font-weight: 600; background: transparent;
}
.meta-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 12px; }
.meta-grid .full { grid-column: 1 / -1; }
.editor-body { min-height: 320px; font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: 13px; line-height: 1.7; }
.dir-status { font-size: 12px; color: var(--muted); }
.field .row { gap: 8px; }
.field .row input { flex: 1; min-width: 0; }
.dir-status.ok { color: var(--accent); }

/* 編輯器很長，回饋必須固定在畫面上，不然按鈕在下面時完全看不到 */
.toast {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%) translateY(8px);
  max-width: min(560px, calc(100% - 32px));
  background: var(--text); color: var(--bg);
  padding: 11px 18px; border-radius: 10px; box-shadow: var(--shadow);
  font-size: 14px; line-height: 1.45; z-index: 100;
  opacity: 0; pointer-events: none;
  transition: opacity .18s ease, transform .18s ease;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.warn { background: var(--chord); color: #fff; }

.editor-body.dropping { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, var(--panel)); }
.preview { max-height: 60vh; overflow: auto; }
.row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.row.end { justify-content: flex-end; }
.msg { font-size: 13px; color: var(--muted); }
.msg.warn { color: var(--chord); }

.help-dlg { max-width: 720px; }
.help-dlg h3 { margin: 18px 0 6px; font-size: 14px; }
.help-table { border-collapse: collapse; width: 100%; font-size: 13px; }
.help-table th, .help-table td { text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--border); vertical-align: top; }
.help-table th { color: var(--muted); font-weight: 600; font-size: 12px; }
.help-table code {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  padding: 1px 5px; border-radius: 4px;
  display: inline-block; word-break: break-all;
}
.help-table td:first-child { white-space: nowrap; }

/* 窄螢幕（含手機）三欄會擠成一個字一行，改成一列一塊由上往下排 */
@media (max-width: 700px) {
  .help-table thead { display: none; }
  .help-table, .help-table tbody, .help-table tr, .help-table td { display: block; width: 100%; }
  .help-table tr { padding: 10px 0; border-bottom: 1px solid var(--border); }
  .help-table td { border: none; padding: 1px 0; }
  .help-table td:first-child { white-space: normal; margin-bottom: 3px; }
  .help-table td:last-child:not(:empty) { margin-top: 5px; }
}

/* 六線譜格子編輯器 */
.tabedit-dlg { max-width: 900px; }
.tabgrid-scroll { overflow-x: auto; padding-bottom: 4px; }
.tabgrid {
  display: grid;
  grid-template-columns: 1.6rem repeat(var(--cols), 2rem);
  gap: 2px; align-items: center; width: max-content;
}
.tabgrid-label {
  font-family: ui-monospace, Consolas, monospace; font-size: 12px;
  color: var(--muted); text-align: right; padding-right: 4px;
}
.tabgrid-cell {
  width: 2rem; padding: 4px 0; text-align: center;
  font-family: ui-monospace, Consolas, monospace; font-size: 13px;
}
/* 有連結線的格子。值本身就看得到 ~，這裡只是讓它在一排數字裡跳出來 */
.tabgrid-cell.tied { border-color: var(--accent); }
.tabgrid-cell:disabled { background: var(--bg); border-color: transparent; }
.tabgrid-cell:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.tabgrid-bar {
  padding: 2px 0; font-size: 11px; color: var(--muted);
  border-color: transparent; background: transparent;
}
/* 用 .picked 而不是 .on —— .on 是全站按鈕的「啟用中」樣式（綠底），
   套在這裡會變成綠底配橘字，完全看不清楚。 */
.tabgrid-bar.picked {
  color: #fff; background: var(--accent);
  border-color: var(--accent); font-weight: 700;
}
.tabgrid-dur { font-size: 12px; color: var(--muted); }
/* 和弦名比格數長，這一列要寬一點才看得完 */
.tabgrid-chord { width: auto; min-width: 2rem; font-size: 11px; color: var(--muted); }
.tabgrid-chord.picked {
  color: var(--chord); font-weight: 700;
  background: color-mix(in srgb, var(--chord) 10%, var(--panel));
  border-color: color-mix(in srgb, var(--chord) 40%, var(--border));
}
.tabgrid-chord:disabled { opacity: .3; }
.tabgrid-dur.picked {
  color: var(--chord); font-weight: 700;
  background: color-mix(in srgb, var(--chord) 12%, var(--panel));
  border-color: color-mix(in srgb, var(--chord) 45%, var(--border));
}
.tabgrid-dur:disabled { opacity: .3; }

.dur-legend {
  display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: center;
  font-size: 12px; color: var(--muted); margin: 0 0 10px;
}
.dur-legend-title { color: var(--text); }
.dur-key code {
  font-family: ui-monospace, Consolas, monospace; font-weight: 700;
  color: var(--chord); background: color-mix(in srgb, var(--chord) 12%, transparent);
  padding: 1px 5px; border-radius: 4px;
}
/* 鎖調那一列：勾選框、調名輸入、說明擠在同一列，說明太長就自己換行 */
.lock-row {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  margin-top: 12px; font-size: 13px;
}
.lock-row input.lock-key {
  width: 5.5em; text-align: center; font-weight: 700;
  color: var(--chord); padding: 4px 6px;
}
.lock-row input.lock-key:disabled { color: var(--muted); font-weight: 400; }
.lock-row .msg { flex: 1 1 100%; margin: 2px 0 0; }

.tabgrid-preview {
  margin: 0; padding: 10px; border-radius: 8px; overflow-x: auto;
  background: var(--bg); border: 1px solid var(--border);
  font-family: ui-monospace, Consolas, monospace; font-size: 12px; line-height: 1.45;
}

dialog {
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--panel); color: var(--text);
  max-width: 700px; width: calc(100% - 32px); padding: 18px;
  box-shadow: var(--shadow);
}
dialog::backdrop { background: rgba(0, 0, 0, .45); }

/* ---------- 手機 ---------- */
@media (max-width: 700px) {
  .more-btn { display: inline-block; }
  /* 手機是用手指按的，觸控目標要夠大 */
  .group > * { min-height: 42px; }
  .group button { min-width: 46px; }
  .toolbar > .tool > button.icon { min-width: 46px; min-height: 42px; }
  .toolbar { gap: 8px; }
  .toolbar .tool-extra { display: none; }
  .toolbar.open .tool-extra { display: flex; flex-wrap: wrap; gap: 8px 12px; width: 100%; }
  .song-head h1 { font-size: 21px; }
  .editor-body { min-height: 240px; }
  .meta-grid { grid-template-columns: 1fr; }
}

/* ---------- 列印 ---------- */
@media print {
  .topbar, .toolbar, .chord-summary, .perf-section { display: none !important; }
  body { background: #fff; color: #000; }
  .wrap { max-width: none; padding: 0; }
  .sheet { font-size: 15px; }
  .line { page-break-inside: avoid; }
}

/* ---------- 會員 ---------- */

/* 鎖住的控制項：看得出來不能用，但還是可以按（按了會說原因）。
   用 disabled 的話按下去毫無反應，使用者只會以為站壞了。 */
.locked { opacity: .5; }
.locked:hover { opacity: .7; }

/* 按到會員功能時才冒出來的說明條，佔整列 */
.member-bar {
  flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: center;
  margin-top: 8px; padding: 8px 12px; border-radius: 8px;
  font-size: 13px; color: var(--text);
  background: color-mix(in srgb, var(--accent) 10%, var(--bg));
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
}
button.link {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--accent); font-weight: 700; text-decoration: underline;
}

/* 登入頁 */
.google-btn { display: flex; justify-content: center; margin: 14px 0 4px; min-height: 44px; }
.or-line {
  display: flex; align-items: center; gap: 10px;
  margin: 16px 0 12px; color: var(--muted); font-size: 12px;
}
.or-line::before, .or-line::after {
  content: ''; flex: 1; height: 1px; background: var(--border);
}

/* 會員管理 */
.user-list { display: flex; flex-direction: column; gap: 8px; }
.user-row {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
  padding: 10px; border: 1px solid var(--border); border-radius: 10px;
}
/* 待核准的要一眼看得出來，那是唯一需要你動手的 */
.user-row.pending { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.user-row .avatar {
  width: 38px; height: 38px; border-radius: 50%; flex: none;
  object-fit: cover; background: var(--border);
}
.user-row .avatar.blank {
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; color: var(--muted);
}
.user-row .who { flex: 1 1 200px; min-width: 0; }
.user-row .name { font-weight: 700; }
.user-row .sub { color: var(--muted); font-size: 12px; word-break: break-all; }
.user-row .when { flex: none; text-align: right; line-height: 1.6; }
.user-row .tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.user-row .acts { flex: none; gap: 6px; }
.tag {
  font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 999px;
  color: var(--muted); border: 1px solid var(--border);
}
.tag.ok { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
.tag.wait { color: var(--chord); border-color: color-mix(in srgb, var(--chord) 40%, transparent); }
.tag.warn { color: var(--chord); background: color-mix(in srgb, var(--chord) 12%, transparent); }

@media (max-width: 700px) {
  .user-row .when { flex: 1 1 100%; text-align: left; }
  .user-row .acts { flex: 1 1 100%; }
}

/* 導覽列上「有人在等核准」的紅點。
   數字直接掛在按鈕上，不另外做通知中心 —— 這個站只有這一種通知。 */
.badge {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  background: var(--chord); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 18px; text-align: center;
}
:root[data-theme="dark"] .badge { color: #201308; }

/* 會員頭像選單。草稿、會員、登出都收在這裡 ——
   全排在導覽列上手機根本放不下。 */
.nav-face-wrap { position: relative; display: inline-flex; }
.nav-face {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 8px; border-radius: 999px;
}
.nav-face img, .nav-face-txt {
  width: 26px; height: 26px; border-radius: 50%;
  object-fit: cover; background: var(--accent); color: var(--panel);
  font-size: 13px; font-weight: 700; line-height: 26px; text-align: center;
}
.nav-face.has-pending { border-color: var(--chord); }

.nav-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 40;
  display: none; flex-direction: column; gap: 2px; min-width: 190px;
  padding: 6px; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--panel); box-shadow: var(--shadow);
}
.nav-menu.open { display: flex; }
.nav-menu button {
  display: flex; align-items: center; gap: 8px;
  justify-content: flex-start; border: none; background: transparent;
  padding: 8px 10px; border-radius: 6px; width: 100%;
}
.nav-menu button:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.nav-who {
  display: flex; flex-direction: column; gap: 1px;
  padding: 6px 10px 8px; border-bottom: 1px solid var(--border); margin-bottom: 4px;
}
.nav-who b { font-size: 13px; }
.nav-who span { font-size: 11px; color: var(--muted); word-break: break-all; }

/* 草稿頁 */
.page-title { font-size: 22px; margin: 22px 0 6px; }
.sub-title { font-size: 14px; color: var(--muted); margin: 22px 0 8px; }

/* ---------- 會員彈唱 ---------- */
.perf-section { border-top: 1px dashed var(--border); margin-top: 8px; padding: 14px 0 32px; }
.perf-title { font-size: 16px; margin: 0 0 10px; }
.perf-count { color: var(--muted); font-weight: 400; font-size: 14px; }

.perf-form { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.perf-form .row { flex-wrap: nowrap; gap: 8px; }
.perf-form .row input { flex: 1; min-width: 0; }
.perf-form .msg { margin: 0; min-height: 1em; }

/* 一張卡片一支影片。寬螢幕排兩欄，手機一欄 */
.perf-list { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); }
.perf-list > .msg { grid-column: 1 / -1; margin: 0; }
.perf-card {
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius);
}
/* 還沒公開的用虛線框，一眼分得出「只有我看得到」 */
.perf-card.status-wait, .perf-card.status-warn { border-style: dashed; }
.perf-card.status-wait { border-color: color-mix(in srgb, var(--chord) 45%, var(--border)); }

/* 播放區：寬的 16:9；Shorts、Reels、TikTok 是直的，限制寬度免得一支佔滿整個畫面 */
.perf-stage { position: relative; aspect-ratio: 16 / 9; background: #000; }
/* 直的影片兩邊留黑邊，寬度限制在 315px（高 560px），不然一支直影片就佔掉整個畫面 */
.perf-stage.tall { aspect-ratio: auto; height: 560px; }
.perf-stage.tall > iframe, .perf-stage.tall > .perf-cover { left: 50%; width: min(100%, 315px); transform: translateX(-50%); }
.perf-stage.audio { aspect-ratio: auto; height: 166px; background: var(--bg); }
.perf-stage iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.perf-cover {
  position: absolute; inset: 0; width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  padding: 0; border: 0; border-radius: 0; cursor: pointer;
  background: color-mix(in srgb, var(--accent) 22%, #111); color: #fff;
}
.perf-cover:hover { border: 0; }
.perf-cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.perf-play {
  position: relative; width: 56px; height: 56px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; background: rgba(0, 0, 0, .6); color: #fff;
  transition: transform .15s;
}
.perf-cover:hover .perf-play { transform: scale(1.08); background: var(--chord); }
.perf-provider {
  position: absolute; left: 8px; bottom: 8px; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 700; background: rgba(0, 0, 0, .6); color: #fff;
}
/* 沒辦法嵌入的網站：整張是連結，矮一點就好 */
.perf-stage.perf-linkcard {
  aspect-ratio: auto; height: 96px; display: flex; align-items: center; justify-content: center; gap: 10px;
  background: color-mix(in srgb, var(--accent) 10%, var(--bg)); color: var(--text); text-decoration: none;
}
.perf-linkcard .perf-play { width: 40px; height: 40px; font-size: 18px; background: var(--accent); color: var(--panel); }
.perf-linkcard .perf-provider { position: static; background: none; color: var(--text); font-size: 14px; }
.perf-linkcard:hover .perf-play { background: var(--chord); }

.perf-info { display: flex; flex-direction: column; gap: 6px; padding: 10px 12px 12px; }
.perf-song { font-weight: 700; color: var(--accent); text-decoration: none; }
.perf-who { display: flex; align-items: center; gap: 8px; font-size: 14px; min-width: 0; }
.perf-who b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.perf-face {
  width: 26px; height: 26px; border-radius: 50%; flex: none; object-fit: cover; background: var(--border);
}
.perf-face.blank { display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; color: var(--muted); }
.perf-date { margin-left: auto; color: var(--muted); font-size: 12px; flex: none; }
.perf-email { margin-top: -4px; color: var(--muted); font-size: 12px; word-break: break-all; }
.perf-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 12px; }
.perf-meta a { color: var(--muted); }
.perf-meta a:hover { color: var(--accent); }
.perf-acts { gap: 6px; flex-wrap: wrap; }
/* 禁止分享會一次下架那個人的全部連結，跟一般按鈕分開顏色 */
button.danger { color: var(--chord); }
button.danger:hover { border-color: var(--chord); }
.perf-tabs { gap: 6px; margin: 14px 0 4px; }

/* 登入頁：平常只有 Google 按鈕，帳密是收起來的備用入口 */
.pw-toggle { font-size: 12px; font-weight: 400; color: var(--muted); text-decoration: underline; }
.pw-toggle:hover { color: var(--accent); }

/* 六線譜編輯器的「完成預覽」：直接用正式的繪製流程畫出來 */
.tabgrid-render {
  overflow-x: auto; padding: 6px 10px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--bg);
}
/* 看譜頁的上下留白在對話框裡太浪費，這裡收掉 */
.tabgrid-render .sheet { padding: 0; }
.tabgrid-render .tab-wrap { margin: 4px 0; }

.tabgrid-raw { margin-top: 10px; }
.tabgrid-raw > summary { cursor: pointer; font-size: 12px; color: var(--muted); }
.tabgrid-raw > summary:hover { color: var(--accent); }
.tabgrid-raw .tabgrid-preview { margin-top: 6px; }

/* ---------- 六線譜格子：分辨現在在哪一條弦 ---------- */
/* 格子一多，左邊的弦名就離很遠（而且會被捲出畫面），很容易填錯線。
   三個對策：弦名固定不捲走、每條弦有自己的顏色、游標所在的那一列整列上色。 */
:root {
  --str-1: #0891b2;  /* e 第一弦 */
  --str-2: #2563eb;  /* B */
  --str-3: #7c3aed;  /* G */
  --str-4: #db2777;  /* D */
  --str-5: #b45309;  /* A */
  --str-6: #15803d;  /* E 第六弦 */
}
:root[data-theme="dark"] {
  --str-1: #67e8f9;
  --str-2: #93c5fd;
  --str-3: #c4b5fd;
  --str-4: #f9a8d4;
  --str-5: #fcd34d;
  --str-6: #86efac;
}

.tabgrid-cell[data-r="0"], .tabgrid-label[data-r="0"] { --str: var(--str-1); }
.tabgrid-cell[data-r="1"], .tabgrid-label[data-r="1"] { --str: var(--str-2); }
.tabgrid-cell[data-r="2"], .tabgrid-label[data-r="2"] { --str: var(--str-3); }
.tabgrid-cell[data-r="3"], .tabgrid-label[data-r="3"] { --str: var(--str-4); }
.tabgrid-cell[data-r="4"], .tabgrid-label[data-r="4"] { --str: var(--str-5); }
.tabgrid-cell[data-r="5"], .tabgrid-label[data-r="5"] { --str: var(--str-6); }

.tabgrid-label[data-r] { color: var(--str); font-weight: 700; }
.tabgrid-cell[data-r] {
  border-color: color-mix(in srgb, var(--str) 40%, var(--border));
  background: color-mix(in srgb, var(--str) 6%, var(--panel));
}
/* 游標所在那一列。整列一起變色，眼睛就不用從最左邊數過來。 */
.tabgrid-cell.row-on {
  background: color-mix(in srgb, var(--str) 20%, var(--panel));
  border-color: var(--str);
}
.tabgrid-label.row-on {
  background: color-mix(in srgb, var(--str) 20%, var(--panel));
  border-radius: 4px;
}

/* 弦名跟著橫向捲動固定在左邊。捲到第 20 欄還看得到自己在第幾弦，
   這才是「填錯線」的根本原因 —— 標籤整個被捲出畫面了。 */
.tabgrid-label {
  position: sticky; left: 0; z-index: 2;
  background: var(--panel);
}

/* ---------- 簡譜區塊 ---------- */
/* 用 grid 而不是 SVG：這裡有中文歌詞，欄寬要讓瀏覽器自己照字量。
   grid-auto-flow: column 加上「每一欄依序放和弦／音符／歌詞」，
   欄寬就會自動取那一欄最寬的內容 —— 中文字比數字寬也不會擠在一起。 */
.jp-block { margin: 14px 0; }
/* 一小節一格，排滿就自動換行 —— 字級調大時不該冒出橫向捲軸，
   譜本來就是一小節一小節看的，斷在小節線上才自然。 */
.jp-lines { display: flex; flex-wrap: wrap; align-items: flex-start; row-gap: .6em; }
.jp-grid {
  display: grid; align-items: end; justify-items: center;
  column-gap: .5em; row-gap: .15em; width: max-content;
  font-family: "SF Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
}
.jp-c { white-space: nowrap; }
/* 每一小節是各自的格線（為了能整小節換行），所以同一列的高度必須自己撐住。
   空格子沒有內容就是 0 高 —— 沒和弦的小節那一列會塌掉，
   有和弦的小節就被推低，看起來像整段跑版。給每一列一個「一行」的最小高度。 */
.jp-chord { color: var(--chord); font-weight: 700; font-size: .78em; line-height: 1.35; min-height: 1.35em; }
.jp-lyric {
  font-family: "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", system-ui, sans-serif;
  line-height: 1.5;
  /* 低音點是絕對定位的、不佔高度，這裡把它需要的空間讓出來。
     沒有低音點時 --lo-clear 不存在，就完全不留白。 */
  padding-top: var(--lo-clear, 0);
  /* 全站是 border-box，min-height 含 padding，所以要一起加上去 */
  min-height: calc(1.5em + var(--lo-clear, 0px));
}
/* 沒有歌詞列的時候，低音點會掉出整塊譜的下緣 */
.jp-lines { padding-bottom: var(--lo-clear, 0); }
/* 簡譜的連音線。畫在數字上方，用半個橢圓。
   跟數字同一列但靠上往上推 —— 排在別的列會把行高擐開，每一行都變高。 */
.jp-tie {
  align-self: start;
  /* .jp-grid 是 justify-items: center，空的 div 會縮成 0 寬 —— 弧線就完全看不見。
     一定要自己撐開，再往內縮一點，兩端才會落在數字上而不是格子的邊。 */
  justify-self: stretch;
  margin-inline: .28em;
  height: .42em; margin-top: -.52em;
  border-top: 1.5px solid currentColor;
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  pointer-events: none;
}
/* 有連音線就要在上面留一點位置，不然弧線會被上一行切掉 */
.jp-lines:has(.jp-tie) { padding-top: .5em; }
/* 弧線是往上推到音符列上方畫的，有和弦的話就正好疊在和弦上。
   把和弦那一列推高一點。要下在整個 `.jp-lines`（不是單一小節），
   否則沒連音的小節不會跟著長高，同一行的音符列就對不齊了。 */
/* 全站是 border-box，min-height 含 padding。沒和弦的格子內容是 0 高，
   只靠 min-height 撒著；有和弦的則是 1.35em + padding。min-height 不一起加上去的話，
   沒和弦的那一小節就比別人矮一截，整個小節往上跑。 */
.jp-lines:has(.jp-tie) .jp-chord { padding-bottom: .45em; min-height: calc(1.35em + .45em); }
/* 編輯器裡有連音線的格子 */
.jp-cell-num.tied { border-color: var(--accent); }
/* 「照 C 大調顯示」的提醒，列印也會跟著出去 */
.jp-do-note { font-size: .72em; color: var(--muted); margin-bottom: .3em; }

/* 開關（看譜頁的「簡譜 C 大調」）。原生 checkbox 藏起來但保留鍵盤操作與讀屏 */
.switch { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; font-size: 14px; position: relative; }
.switch input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.switch-track {
  position: relative; flex: none; width: 38px; height: 22px; border-radius: 999px;
  background: var(--border); transition: background .15s ease;
}
.switch-track::after {
  content: ''; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .25);
  transition: transform .15s ease;
}
.switch input:checked + .switch-track { background: var(--accent); }
.switch input:checked + .switch-track::after { transform: translateX(16px); }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--accent); outline-offset: 2px; }
/* 八度的「自動／升 8 度」夾在 − ＋ 中間 */
.oct-out { display: flex; align-items: center; justify-content: center; padding: 0 10px; min-width: 5.5em; font-size: 13px; }
/* 簡譜編輯器：按了換算但這首不用換時的提示 */
.fix-hint { color: var(--chord); font-weight: 600; }
/* 音符列上下要留白給八度點，點是絕對定位的，不留就會壓到和弦與歌詞 */
.jp-n {
  display: flex; align-items: baseline; gap: .1em;
  padding: .55em 0 .12em; white-space: nowrap; line-height: 1.2;
  min-height: calc(1.2em + .67em);
}
.jp-num { font-weight: 600; }
/* 底線代表比一拍短（八分一條、十六分兩條）。
   畫成獨立的一列、橫跨整組 —— 同一拍裡的音底線要連成一條，
   一格一格各自畫的話會變成斷斷續續的短線，看不出是一組。 */
.jp-beam {
  align-self: start; justify-self: stretch;
  height: 0; border-top: 1px solid var(--text);
  /* 底線要緊貼數字。放在獨立的一列、又隔著列距的話，
     它會掉到低音點下面去，看起來像跟別的音有關係。 */
  margin-top: -.42em;
}
.jp-beam.lv2 { margin-top: calc(-.42em + 3px); }
/* 超過一拍的橫線與附點 */
.jp-hold { color: var(--muted); padding: 0 .05em; }
.jp-dotted { font-weight: 700; }
/* 小節線畫成一條直的，不是字 */
.jp-bar {
  padding: 0; align-self: stretch; justify-self: center;
  border-left: 1px solid var(--muted); width: 0; margin: 0 .25em;
}

/* 簡譜格子編輯器。欄多列少，跟六線譜相反，所以標題在左、每欄一直排。 */
.jpgrid {
  display: grid;
  grid-template-columns: 2.6rem repeat(var(--cols), 2.4rem);
  gap: 2px; align-items: center; width: max-content;
}
.jpgrid-label {
  position: sticky; left: 0; z-index: 2; background: var(--panel);
  font-size: 12px; color: var(--muted); text-align: right; padding-right: 6px;
}
/* 游標所在那一欄整欄上色 —— 欄位一多，上下對不起來就會填錯音 */
.jpgrid .col-on { background: color-mix(in srgb, var(--accent) 14%, var(--panel)); }
.jpgrid .tabgrid-cell, .jpgrid .tabgrid-bar { width: 2.4rem; }
.jp-cell-num { font-weight: 700; font-size: 15px; }
.jp-cell-lyric { font-size: 12px; padding: 4px 2px; }
.jp-oct {
  font-size: 11px; color: var(--muted); padding: 4px 0;
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
}
.jp-oct.picked {
  color: var(--accent); font-weight: 700;
  background: color-mix(in srgb, var(--accent) 12%, var(--panel));
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
}
.jp-oct:disabled { opacity: .3; }

/* 簡譜區塊裡的八度點要另外定位。
   歌詞行那一套偏移是照「文字行裡的字」調的，這裡數字包在自己的方塊裡，
   同樣的 top 值會落在數字身上而不是上方 —— 點就被數字蓋掉，等於沒畫。 */
.jp-n .jp-hi .jp-dot { top: calc(-0.12em - var(--i) * 0.26em); }
/* 有底線時低音點要再往下讓開，不然點會壓在底線上 */
.jp-n .jp-lo .jp-dot { bottom: calc(-0.06em - var(--i) * 0.24em - var(--under, 0) * 0.2em); }

/* ---------- 和弦指板圖 ---------- */
.chord-summary { gap: 10px 8px; align-items: flex-start; }
.cd-box {
  margin: 0; display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 6px 4px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--panel); min-width: 62px;
}
.cd-box figcaption { font-weight: 700; color: var(--chord); font-size: 13px; white-space: nowrap; }
/* 查不到指法的和弦只顯示名字，不要留一塊空白的指板 */
.cd-none { padding: 6px 10px; }
.cd { width: 62px; height: auto; display: block; }

.cd-line { stroke: var(--muted); stroke-width: 1; }
.cd-nut { stroke: var(--text); stroke-width: 3; }
.cd-dot { fill: var(--text); }
.cd-barre { stroke: var(--text); stroke-width: 9; stroke-linecap: round; }
.cd-finger { fill: var(--panel); font-size: 7px; font-weight: 700; text-anchor: middle; }
.cd-open { fill: none; stroke: var(--text); stroke-width: 1.2; }
.cd-mute { stroke: var(--muted); stroke-width: 1.4; }
.cd-base { fill: var(--muted); font-size: 8px; font-weight: 700; text-anchor: end; }

/* 列印時指板圖要留著 —— 那是譜的一部分，不是螢幕上的工具 */
@media print {
  .chord-summary { display: flex !important; }
  .cd-box { break-inside: avoid; }
}

/* 和弦指法編輯器 */
.chordedit-dlg { max-width: 640px; }
/* 指法目前用哪一份、存到哪裡 */
.ce-scope { margin-top: 6px; }
.ce-body { display: flex; flex-wrap: wrap; gap: 20px; align-items: flex-start; margin: 14px 0 4px; }
.ce-grid {
  display: grid; grid-template-columns: 1.8rem repeat(6, 2.1rem);
  gap: 3px; align-items: center;
}
.ce-rowlab { font-size: 11px; color: var(--muted); text-align: right; padding-right: 4px; }
.ce-strlab { font-size: 10px; color: var(--muted); text-align: center; }
.ce-barre-btn {
  background: transparent; border: 1px solid transparent; border-radius: 6px;
  padding: 2px 4px; font-size: 11px; color: var(--muted); text-align: right;
}
.ce-barre-btn:hover { border-color: var(--accent); color: var(--accent); }
/* 用 .picked 不用 .on —— .on 是全站按鈕的「啟用中」樣式（綠底白字），
   套在這裡會把自己的配色蓋掉，最上面那排的 ○ ✕ 會變成綠底綠字，整個看不見。 */
.ce-barre-btn.picked { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 700; }
:root[data-theme="dark"] .ce-barre-btn.picked { color: #10201c; }
.ce-top {
  padding: 2px 0; font-size: 13px; line-height: 1.4;
  border: 1px solid var(--border); border-radius: 6px; background: var(--panel);
}
.ce-top.picked { border-color: var(--accent); color: var(--accent); font-weight: 700; }
.ce-cell {
  height: 30px; padding: 0; border: 1px solid var(--border); border-radius: 6px;
  background: var(--panel); font-size: 12px; font-weight: 700; color: var(--muted);
}
.ce-cell:hover { border-color: var(--accent); }
.ce-cell.picked { background: var(--text); border-color: var(--text); color: var(--panel); }
/* 屬於橫按的格子標一下，才看得出那一條線蓋到哪 */
.ce-cell.barre { box-shadow: inset 0 0 0 2px var(--accent); }
.ce-side { display: flex; flex-direction: column; gap: 10px; }
.ce-preview .cd-box { min-width: 78px; }
.ce-baserow { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); }
.ce-base { width: 5rem; }
.ce-hint { font-size: 11px; color: var(--muted); max-width: 12rem; line-height: 1.5; }

/* 和弦圖上的「改指法」，平常低調，滑到才明顯 */
.cd-edit {
  margin-top: 2px; padding: 1px 6px; font-size: 10px;
  color: var(--muted); background: transparent;
  border: 1px solid var(--border); border-radius: 999px;
}
.cd-edit:hover { color: var(--accent); border-color: var(--accent); }
@media print { .cd-edit { display: none !important; } }

/* 已經自訂過的和弦標一下，才看得出哪些被改過 */
/* 看譜頁「用到的和弦」旁邊的「改指法」開關 */
.chord-summary .shape-switch { font-size: 13px; margin-right: 6px; }
/* 這首譜自訂的指法標「自訂」，用強調色；內建的（整個譜庫一樣）不標 */
.cd-tag.song { color: var(--accent); border-color: var(--accent); }
.cd-tag {
  font-size: 10px; font-weight: 700; color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  border-radius: 999px; padding: 0 6px; margin-top: 2px;
}

/* 簡譜的升降記號：畫在數字左上角，跟數字一樣大。
   記號要一眼認得出是升還是降，不然譜就是錯的 ——
   縮小就會跟旁邊的數字糊在一起。
   對齊基線再往上提，不是對齊整個格子的頂端：那會被上面的八度點空間
   推得太高，看起來像浮在旁邊、分不出屬於哪個數字。 */
.jp-acc {
  font-size: 1em; font-weight: 700; line-height: 1;
  align-self: baseline; position: relative; top: -.3em;
  margin-right: .02em;
}
