/* =========================================================================
   VALKO / 敖尹 聲援站 — "Moonlit Steel 月下鋼鐵"
   原創設計系統 · 無使用任何官方美術素材
   Palette: 槍鐵炭黑 base · 血緋 crimson · 熔金 gold · 鋼銀 steel · 月白 moon
   ========================================================================= */

:root {
  /* --- surfaces --- */
  --bg: #0b0c10;
  --bg-2: #101218;
  --panel: #14161e;
  --panel-2: #191c26;
  --line: #262a36;
  --line-soft: #1d2029;

  /* --- ink --- */
  --ink: #e7e9f0;
  --ink-soft: #aab0c0;
  --ink-mute: #737a8c;

  /* --- accents --- */
  --crimson: #d8324a;
  --crimson-2: #ec526a;
  --gold: #d8ab5a;
  --gold-2: #f0d38c;
  --steel: #aeb6c6;
  --moon: #eef1fa;

  /* --- effects --- */
  --glow-moon: 0 0 90px 20px rgba(220, 226, 245, .10);
  --glow-red: 0 0 34px rgba(216, 50, 74, .35);
  --shadow: 0 24px 60px -22px rgba(0, 0, 0, .75);

  --maxw: 1120px;
  --ease: cubic-bezier(.2, .7, .2, 1);

  --font-display: "Cinzel", "Noto Serif TC", "Noto Serif JP", serif;
  --font-body: "Noto Serif TC", "Noto Serif JP", "EB Garamond", Georgia, serif;
  --font-sans: "Zen Kaku Gothic New", "Noto Sans TC", system-ui, sans-serif;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.8;
  letter-spacing: .01em;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* grain + vignette atmosphere */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background:
    radial-gradient(120% 80% at 50% -10%, rgba(30, 34, 48, .55), transparent 60%),
    radial-gradient(100% 100% at 50% 120%, rgba(216, 50, 74, .06), transparent 55%);
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 2;
  opacity: .05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

.wrap {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 26px;
  position: relative;
  z-index: 3;
}

.narrow {
  max-width: 820px;
}

/* ---------- Typography ---------- */
h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: .02em;
}

.eyebrow {
  font-family: var(--font-sans);
  font-size: .74rem;
  letter-spacing: .42em;
  text-transform: uppercase;
  color: var(--gold);
  font-weight: 600;
}

.gold-text {
  background: linear-gradient(100deg, var(--gold) 0%, var(--gold-2) 45%, #b98b3d 70%, var(--gold-2) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.crimson {
  color: var(--crimson-2);
}

a {
  color: var(--gold-2);
  text-decoration: none;
  transition: color .2s;
}

a:hover {
  color: var(--crimson-2);
}

/* ---------- Nav ---------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(11, 12, 16, .72);
  backdrop-filter: blur(14px) saturate(1.2);
  border-bottom: 1px solid var(--line-soft);
}

.nav-inner {
  display: flex;
  align-items: center;
  gap: 14px;
  height: 66px;
  max-width: 1400px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-display);
  font-size: 1.06rem;
  letter-spacing: .16em;
  color: var(--moon);
  flex: 0 0 auto;
}

.brand .glyph {
  width: 26px;
  height: 26px;
  flex: 0 0 auto;
}

/* 導覽連結：統一為分組下拉面板（桌機與手機一致，點「選單」鈕展開） */
.nav-links {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  flex-direction: column;
  gap: 2px;
  min-width: 244px;
  max-height: calc(100vh - 90px);
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: var(--shadow);
  padding: 8px;
  z-index: 50;
}

.nav-links.open {
  display: flex;
  animation: navpop .18s var(--ease);
}

@keyframes navpop {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.nav-links a {
  font-family: var(--font-sans);
  font-size: .9rem;
  letter-spacing: .02em;
  white-space: nowrap;
  color: var(--ink);
  padding: 10px 14px;
  border-radius: 10px;
  transition: color .18s, background .18s;
}

.nav-links a:hover {
  color: var(--moon);
  background: rgba(255, 255, 255, .06);
}

.nav-links a.active {
  color: var(--bg);
  background: linear-gradient(100deg, var(--gold), var(--gold-2));
}

/* 置頂強調項（聲援總部） */
.nav-links .nav-featured {
  display: flex;
  align-items: center;
  gap: 9px;
  color: var(--moon);
  font-weight: 600;
  background: rgba(216, 50, 74, .12);
  border: 1px solid rgba(216, 50, 74, .32);
}

.nav-links .nav-featured::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--crimson-2);
  box-shadow: 0 0 8px rgba(236, 82, 106, .9);
  flex: 0 0 auto;
}

.nav-links .nav-featured:hover {
  background: rgba(216, 50, 74, .2);
  color: var(--moon);
}

.nav-links .nav-featured.active {
  color: var(--moon);
  background: rgba(216, 50, 74, .24);
  border-color: var(--crimson-2);
}

/* 分組（手風琴：點母分類展開子項） */
.nav-group {
  margin-top: 4px;
  padding-top: 6px;
  border-top: 1px solid var(--line-soft);
}

.nav-group-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-sans);
  font-size: .84rem;
  letter-spacing: .02em;
  font-weight: 500;
  color: var(--gold-2);
  padding: 10px 14px;
  border-radius: 10px;
  transition: color .18s, background .18s;
}

.nav-group-toggle:hover {
  color: var(--gold);
  background: rgba(255, 255, 255, .05);
}

.nav-group.open .nav-group-toggle {
  color: var(--gold);
}

.nav-group-chevron {
  width: 7px;
  height: 7px;
  flex: 0 0 auto;
  margin-bottom: 2px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform .22s var(--ease);
}

.nav-group.open .nav-group-chevron {
  transform: rotate(-135deg);
  margin-bottom: -2px;
}

.nav-group-items {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 0;
  overflow: hidden;
  transition: max-height .26s var(--ease);
}

/* 展開高度上限＝收合動畫的終點，必須大於「項目最多的那一組」的實際高度。
   ⚠ 往任何一組加選單項目時要回來看這個數字：超過就會被 overflow:hidden 切掉，
     使用者看到的是一個少了最後一項、而且沒有任何錯誤的選單。
     目前最多的是「紀念與創作」6 項（約 250px），340 留了兩項的餘裕。 */
.nav-group.open .nav-group-items {
  max-height: 340px;
}

.lang-switch {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}

.lang-select {
  font-family: var(--font-sans);
  font-size: .78rem;
  letter-spacing: .04em;
  color: var(--ink-soft);
  background-color: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 7px 30px 7px 14px;
  cursor: pointer;
  line-height: 1;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23737a8c' stroke-width='1.4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  transition: border-color .2s, color .2s;
}

.lang-select:hover {
  border-color: var(--gold);
  color: var(--moon);
}

.lang-select:focus-visible {
  outline: none;
  border-color: var(--gold);
}

.lang-select option {
  background: var(--bg-2);
  color: var(--ink);
}

/* 選單鈕：桌機與手機皆顯示的藥丸按鈕 */
.nav-toggle {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-left: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink-soft);
  cursor: pointer;
  line-height: 1;
  font-family: var(--font-sans);
  font-size: .8rem;
  letter-spacing: .04em;
  padding: 7px 15px;
  transition: border-color .2s, color .2s;
}

.nav-toggle:hover,
.nav-toggle[aria-expanded="true"] {
  border-color: var(--gold);
  color: var(--moon);
}

.nav-toggle .nav-bars {
  display: inline-flex;
  flex-direction: column;
  gap: 3px;
  width: 15px;
}

.nav-toggle .nav-bars i {
  height: 1.6px;
  background: currentColor;
  border-radius: 2px;
  transition: transform .2s, opacity .2s;
}

.nav-toggle[aria-expanded="true"] .nav-bars i:nth-child(1) {
  transform: translateY(4.6px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-bars i:nth-child(2) {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-bars i:nth-child(3) {
  transform: translateY(-4.6px) rotate(-45deg);
}

.nav-toggle .nav-toggle-label {
  display: inline-block;
}

/* 桌機（≥1000px）：母分類直接排在導覽列，各自點開下拉；隱藏漢堡鈕。
   斷點取 1000px：最長語言（西班牙文）單行約需 895px，留足餘裕避免溢出把語言選單擠掉。
   注意：本區塊須置於上方所有導覽基礎樣式（.nav-toggle / .nav-links / .nav-group）之後，
   否則同權重下會被後面的基礎規則覆蓋。 */
@media (min-width: 1000px) {
  .nav-toggle {
    display: none;
  }

  .nav-links {
    display: flex;
    position: static;
    margin-left: auto;
    flex-direction: row;
    align-items: center;
    gap: 3px;
    min-width: 0;
    max-height: none;
    overflow: visible;
    background: none;
    border: 0;
    box-shadow: none;
    padding: 0;
    animation: none;
  }

  .nav-links .nav-featured {
    padding: 7px 12px;
    font-size: .82rem;
    gap: 7px;
  }

  .nav-links .nav-featured::before {
    width: 6px;
    height: 6px;
  }

  .nav-group {
    position: relative;
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
  }

  .nav-group-toggle {
    font-size: .82rem;
    padding: 8px 11px;
    gap: 6px;
    color: var(--ink-soft);
    white-space: nowrap;
  }

  .nav-group-toggle:hover {
    color: var(--moon);
    background: rgba(255, 255, 255, .05);
  }

  .nav-group.has-active .nav-group-toggle {
    color: var(--gold-2);
  }

  .nav-group.open .nav-group-toggle {
    color: var(--gold);
  }

  .nav-group-chevron {
    width: 6px;
    height: 6px;
  }

  .nav-group-items {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    right: auto;
    z-index: 50;
    min-width: 204px;
    max-height: none;
    overflow: visible;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 14px;
    box-shadow: var(--shadow);
    padding: 8px;
  }

  /* 最右側分組（關於本站）靠右錨定避免溢出；寬度依內容自適應，避免過寬往左浮出脫節 */
  .nav-links .nav-group:last-of-type .nav-group-items {
    left: auto;
    right: 0;
    min-width: 0;
    width: max-content;
  }

  /* max-height 要在這裡再解一次。上面那條 .nav-group.open .nav-group-items 的
     權重（0,3,0）比本區塊 .nav-group-items 的（0,1,0）高，光靠那邊的
     max-height:none 蓋不掉——桌機的下拉會被壓在手機版的收合高度裡，
     背景框只包住前幾項，其餘因為 overflow:visible 露在框外。
     桌機這個下拉是絕對定位的浮動框，本來就不需要收合動畫，直接解除上限。 */
  .nav-group.open .nav-group-items {
    display: flex;
    max-height: none;
    animation: navpop .18s var(--ease);
  }

  .nav-links a {
    font-size: .86rem;
  }
}

/* ---------- Moon motif ---------- */
.moon {
  position: relative;
  border-radius: 50%;
  background:
    radial-gradient(circle at 38% 34%, #fbfcff 0%, #dfe4f0 26%, #aeb6c8 60%, #7d8496 100%);
  box-shadow: var(--glow-moon), inset -14px -12px 40px rgba(20, 24, 38, .6), inset 10px 8px 30px rgba(255, 255, 255, .35);
}

.moon::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  opacity: .5;
  mix-blend-mode: multiply;
  background:
    radial-gradient(circle at 62% 30%, rgba(90, 98, 120, .5) 0 5%, transparent 6%),
    radial-gradient(circle at 40% 62%, rgba(90, 98, 120, .45) 0 7%, transparent 8%),
    radial-gradient(circle at 70% 66%, rgba(90, 98, 120, .4) 0 4%, transparent 5%),
    radial-gradient(circle at 30% 40%, rgba(90, 98, 120, .4) 0 3%, transparent 4%);
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  padding: 96px 0 70px;
  overflow: hidden;
}

.hero-moon {
  position: absolute;
  width: 460px;
  height: 460px;
  right: -60px;
  top: 40px;
  z-index: 0;
  opacity: .9;
}

.hero-grid {
  position: relative;
  z-index: 3;
  display: grid;
  gap: 12px;
  max-width: 760px;
}

.hero h1 {
  font-size: clamp(3rem, 9vw, 6.4rem);
  margin: 6px 0 4px;
  letter-spacing: .04em;
  text-shadow: 0 2px 40px rgba(0, 0, 0, .6);
}

.hero .cn-name {
  font-family: var(--font-body);
  font-size: clamp(1.2rem, 3.4vw, 1.9rem);
  color: var(--steel);
  letter-spacing: .5em;
}

.hero .lead {
  font-size: 1.16rem;
  color: var(--ink-soft);
  max-width: 560px;
  margin-top: 14px;
}

.hero .dates {
  display: inline-flex;
  gap: 18px;
  margin-top: 24px;
  flex-wrap: wrap;
  font-family: var(--font-sans);
  font-size: .8rem;
  letter-spacing: .05em;
  color: var(--ink-mute);
}

.hero .dates b {
  color: var(--crimson-2);
  font-weight: 600;
}

.hero .dates s {
  color: var(--ink-mute);
}

.btn-row {
  display: flex;
  gap: 14px;
  margin-top: 32px;
  flex-wrap: wrap;
}

.btn {
  font-family: var(--font-sans);
  font-size: .86rem;
  letter-spacing: .06em;
  padding: 13px 24px;
  border-radius: 999px;
  cursor: pointer;
  border: 1px solid transparent;
  transition: all .25s var(--ease);
  display: inline-flex;
  align-items: center;
  gap: 9px;
}

.btn-primary {
  background: linear-gradient(100deg, var(--crimson), var(--crimson-2));
  color: #fff;
  box-shadow: var(--glow-red);
}

.btn-primary:hover {
  transform: translateY(-2px);
  color: #fff;
}

/* background 一定要寫：全站其他地方 .btn 都掛在 <a> 上（預設就是透明），
   但掛在 <button> 上時瀏覽器預設是 buttonface（淺灰/白），會變成一顆白按鈕。 */
.btn-ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--ink-soft);
}

.btn-ghost:hover {
  border-color: var(--gold);
  color: var(--moon);
}

/* ---------- Sections ---------- */
section.block {
  padding: 74px 0;
  border-top: 1px solid var(--line-soft);
}

.sec-head {
  margin-bottom: 40px;
}

.sec-head h2 {
  font-size: clamp(1.8rem, 4.4vw, 2.8rem);
  margin: 10px 0 0;
}

.sec-head p {
  color: var(--ink-soft);
  max-width: 640px;
}

/* pupil divider bullet */
.pupil {
  display: inline-block;
  width: 12px;
  height: 20px;
  vertical-align: middle;
  background: radial-gradient(ellipse 50% 50% at 50% 50%, var(--gold-2), var(--gold) 40%, #7a5a24 75%);
  border-radius: 50%;
  box-shadow: 0 0 10px rgba(216, 171, 90, .6);
}

/* ---------- Stat strip ---------- */
/* 四欄不等寬：「身分」那格的值最長（EonCore 董事長＋狼人家族頭領），等寬會把它
   擠成三行，而「26」「189」兩格空一大半。 */
.stats {
  display: grid;
  grid-template-columns: 1.7fr 1fr 1fr 1.15fr;
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: 16px;
  overflow: hidden;
}

.stat {
  background: var(--panel);
  padding: 24px 20px;
}

.stat .k {
  font-family: var(--font-sans);
  font-size: .68rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.stat .v {
  font-family: var(--font-display);
  font-size: 1.7rem;
  margin-top: 8px;
  color: var(--moon);
}

.stat .v small {
  font-size: .8rem;
  color: var(--ink-soft);
}

/* 這條列跟著頁面其他區塊收成 .narrow 寬度後空間變小：值改小一級，行高也從 body
   的 1.8 收到 1.35，否則「· 狼人家族頭領」掉到次行時中間會空一大塊。
   只縮這條列，不動同人頁的 .tribute-stats。 */
.stats .stat {
  padding: 20px 18px;
}

.stats .stat .v {
  font-size: 1.5rem;
  line-height: 1.35;
}

/* ---------- Cards ---------- */
.grid {
  display: grid;
  gap: 20px;
}

.grid.cols-2 {
  grid-template-columns: repeat(2, 1fr);
}

.grid.cols-3 {
  grid-template-columns: repeat(3, 1fr);
}

.card {
  background: linear-gradient(160deg, var(--panel), var(--bg-2));
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 28px;
  position: relative;
  transition: transform .3s var(--ease), border-color .3s;
}

.card:hover {
  transform: translateY(-4px);
  border-color: rgba(216, 171, 90, .4);
}

.card h3 {
  font-size: 1.24rem;
  margin: 0 0 10px;
  color: var(--moon);
}

.card .num {
  font-family: var(--font-display);
  font-size: 2.4rem;
  color: rgba(216, 50, 74, .35);
  line-height: 1;
}

.card p {
  color: var(--ink-soft);
  margin: 8px 0;
  font-size: .98rem;
}

.card .label {
  font-family: var(--font-sans);
  font-size: .68rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--gold);
  display: block;
  margin-top: 14px;
}

/* profile rows */
.prow {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 24px;
  padding: 26px 0;
  border-top: 1px solid var(--line-soft);
}

.prow:last-child {
  border-bottom: 1px solid var(--line-soft);
}

.prow .plabel {
  font-family: var(--font-display);
  font-size: 1.15rem;
  color: var(--gold-2);
  letter-spacing: .04em;
}

.prow .pbody {
  color: var(--ink-soft);
}

.prow .pbody strong {
  color: var(--moon);
  font-weight: 600;
}

/* ---------- Timeline ---------- */
.timeline {
  position: relative;
  margin-top: 20px;
  padding-left: 34px;
}

.timeline::before {
  content: "";
  position: absolute;
  left: 9px;
  top: 6px;
  bottom: 6px;
  width: 2px;
  background: linear-gradient(var(--crimson), var(--gold), transparent);
}

.tl-item {
  position: relative;
  padding: 0 0 34px;
}

.tl-item::before {
  content: "";
  position: absolute;
  left: -30px;
  top: 6px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--crimson);
  box-shadow: 0 0 0 4px rgba(216, 50, 74, .16);
}

.tl-item .date {
  font-family: var(--font-sans);
  font-size: .78rem;
  letter-spacing: .1em;
  color: var(--gold);
}

.tl-item h4 {
  font-family: var(--font-display);
  font-size: 1.16rem;
  margin: 4px 0 6px;
  color: var(--moon);
}

.tl-item p {
  color: var(--ink-soft);
  margin: 0;
  font-size: .96rem;
}

/* ---------- Split viewpoint (argument / response) ---------- */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  margin-top: 16px;
}

.split>div {
  padding: 22px 24px;
}

.split .claim {
  background: rgba(216, 50, 74, .06);
  border-right: 1px solid var(--line);
}

.split .resp {
  background: rgba(216, 171, 90, .05);
}

.split .tag {
  font-family: var(--font-sans);
  font-size: .68rem;
  letter-spacing: .16em;
  text-transform: uppercase;
}

.split .claim .tag {
  color: var(--crimson-2);
}

.split .resp .tag {
  color: var(--gold-2);
}

.split p {
  margin: 8px 0 0;
  color: var(--ink-soft);
  font-size: .96rem;
}

/* ---------- Do / Don't ---------- */
.dodont {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}

.dobox,
.dontbox {
  border-radius: 16px;
  padding: 24px;
  border: 1px solid var(--line);
}

.dobox {
  background: rgba(120, 180, 140, .05);
}

.dontbox {
  background: rgba(216, 50, 74, .06);
}

.dobox h3 {
  color: #8fd6a6;
}

.dontbox h3 {
  color: var(--crimson-2);
}

.dodont ul {
  list-style: none;
  padding: 0;
  margin: 12px 0 0;
}

.dodont li {
  padding: 7px 0 7px 26px;
  position: relative;
  color: var(--ink-soft);
  font-size: .96rem;
}

.dobox li::before {
  content: "✓";
  position: absolute;
  left: 0;
  color: #8fd6a6;
}

.dontbox li::before {
  content: "✕";
  position: absolute;
  left: 0;
  color: var(--crimson-2);
}

/* ---------- Channels ---------- */
.channel {
  display: grid;
  grid-template-columns: 48px 1fr;
  gap: 18px;
  padding: 24px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 16px;
  transition: border-color .3s;
}

.channel:hover {
  border-color: rgba(216, 171, 90, .4);
}

.channel .ic {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  background: rgba(216, 171, 90, .12);
  color: var(--gold-2);
}

.channel h3 {
  font-size: 1.1rem;
  margin: 0 0 4px;
  color: var(--moon);
}

.channel p {
  margin: 0;
  color: var(--ink-soft);
  font-size: .95rem;
}

/* ---------- Template box ---------- */
.tmpl {
  background: var(--bg-2);
  border: 1px dashed var(--line);
  border-radius: 14px;
  padding: 22px 24px;
  margin-top: 14px;
  position: relative;
}

.tmpl pre {
  font-family: var(--font-sans);
  white-space: pre-wrap;
  margin: 0;
  color: var(--ink-soft);
  font-size: .92rem;
  line-height: 1.7;
}

.copy-btn {
  position: absolute;
  top: 14px;
  right: 14px;
  font-family: var(--font-sans);
  font-size: .72rem;
  background: rgba(216, 171, 90, .12);
  color: var(--gold-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 5px 12px;
  cursor: pointer;
}

.copy-btn:hover {
  background: var(--gold);
  color: var(--bg);
}

/* ---------- Doujin wall ---------- */
.wall {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}

.tribute {
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  background: var(--panel);
}

.tribute .art {
  aspect-ratio: 4/3;
  display: grid;
  place-items: center;
  position: relative;
  background: radial-gradient(circle at 50% 35%, #1b1f2b, #0c0d12);
}

.tribute .art .moon {
  width: 84px;
  height: 84px;
  opacity: .8;
}

.tribute .art .ph {
  position: absolute;
  bottom: 12px;
  font-family: var(--font-sans);
  font-size: .68rem;
  letter-spacing: .14em;
  color: var(--ink-mute);
  text-transform: uppercase;
}

.tribute .meta {
  padding: 16px 18px;
}

.tribute .meta .by {
  font-family: var(--font-display);
  color: var(--gold-2);
  font-size: 1rem;
}

.tribute .meta .note {
  color: var(--ink-soft);
  font-size: .88rem;
  margin-top: 4px;
}

.tribute .meta .plat {
  font-family: var(--font-sans);
  font-size: .7rem;
  color: var(--ink-mute);
  letter-spacing: .1em;
  margin-top: 8px;
}

a.art {
  cursor: zoom-in;
  text-decoration: none;
}

.tribute .art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
  transition: transform .5s var(--ease);
}

.tribute:hover .art img {
  transform: scale(1.045);
}

.tribute .meta .by a {
  color: inherit;
}

.tribute .meta .by a:hover {
  color: var(--crimson-2);
}

/* ---- 同人聲援牆：老師 → 系列 → 作品（卡片瀑布流） ---- */
/* 熱度統計 */
.tribute-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: 14px;
  overflow: hidden;
  margin-bottom: 32px;
}

.tribute-stats .stat {
  background: var(--panel);
  padding: 20px 16px;
  text-align: center;
}

@media (max-width: 480px) {
  .tribute-stats {
    grid-template-columns: 1fr;
  }
}

/* 卡片瀑布流：每位老師一張卡，依內容長高、交錯緊排 */
.artists {
  column-width: 320px;
  column-gap: 22px;
}

.artist {
  break-inside: avoid;
  margin: 0 0 22px;
  border: 1px solid var(--line-soft);
  border-radius: 16px;
  background: var(--panel);
  overflow: hidden;
}

.artist-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 14px;
  flex-wrap: wrap;
  padding: 13px 16px;
  border-bottom: 1px solid var(--line-soft);
  background: rgba(255, 255, 255, .015);
}

.artist-id {
  display: flex;
  align-items: baseline;
  gap: 9px;
  flex-wrap: wrap;
  min-width: 0;
}

.artist-name {
  font-family: var(--font-display);
  font-size: 1.08rem;
  color: var(--gold-2);
  word-break: break-all;
}

.artist-name a {
  color: inherit;
}

.artist-name a:hover {
  color: var(--crimson-2);
}

.artist-plat {
  font-family: var(--font-sans);
  font-size: .64rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.artist-count {
  font-family: var(--font-sans);
  font-size: .7rem;
  letter-spacing: .04em;
  color: var(--ink-mute);
}

.artist-link {
  font-family: var(--font-sans);
  font-size: .74rem;
  letter-spacing: .04em;
  color: var(--steel);
  white-space: nowrap;
}

.artist-link:hover {
  color: var(--gold-2);
}

.artist-body {
  padding: 14px 16px 16px;
}

.series+.series {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line-soft);
}

.series-title {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 11px;
  font-family: var(--font-display);
  font-size: .98rem;
  font-weight: 600;
  color: var(--moon);
}

.series-title .series-count {
  font-family: var(--font-sans);
  font-size: .62rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

/* 卡內單欄堆疊，讓每張圖放大、完整呈現（不裁切） */
.series-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}

.work {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg-2);
}

.work .art {
  display: block;
  overflow: hidden;
  cursor: zoom-in;
  line-height: 0;
  position: relative;
}

/* width/height 屬性 + height:auto → 瀏覽器依原始比例預留版位，載入時不跳動 */
.work .art img {
  width: 100%;
  height: auto;
  display: block;
  transition: transform .5s var(--ease);
}

.work .art video {
  width: 100%;
  height: auto;
  display: block;
  background: #000;
  transition: transform .5s var(--ease);
}

.work:hover .art img,
.work:hover .art video {
  transform: scale(1.04);
}

/* 影片作品：右上角小標記，提示這是影片、點擊看原作 */
.work--video .art::after {
  content: "▶";
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: rgba(11, 12, 16, .68);
  color: #fff;
  font-size: .6rem;
  display: grid;
  place-items: center;
  pointer-events: none;
}

.work figcaption {
  padding: 8px 12px;
  font-size: .82rem;
  color: var(--ink-soft);
  line-height: 1.4;
}

/* 超過預覽張數的作品預設收合，點「展開更多」就地展開 */
.artist:not(.is-expanded) .work--overflow,
.artist:not(.is-expanded) .series--overflow {
  display: none;
}

.artist-toggle {
  margin-top: 14px;
  background: none;
  border: 1px solid var(--line);
  color: var(--gold-2);
  font-family: var(--font-sans);
  font-size: .76rem;
  letter-spacing: .06em;
  padding: 7px 16px;
  border-radius: 999px;
  cursor: pointer;
  transition: border-color .18s, color .18s, background .18s;
}

.artist-toggle:hover {
  border-color: var(--gold);
  color: var(--moon);
  background: rgba(255, 255, 255, .04);
}

/* ---------- Rumor vs Truth 逐條闢謠圖卡 ---------- */
/* 圖卡本身有中/英兩版，src 由 main.js 依當前語言替換（data-i18n-src 的 {lang}）。 */
/* 九張圖卡 → 桌機三欄（3×3 剛好排滿，不會留空位）；≤860px 收成單欄 */
.rumors {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.rumor {
  margin: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 18px;
  transition: transform .3s var(--ease), border-color .3s;
}

.rumor:hover {
  transform: translateY(-3px);
  border-color: rgba(216, 171, 90, .4);
}

.rumor-txt {
  padding: 22px 24px 18px;
}

.rumor-txt p {
  margin: 0;
  font-size: .96rem;
  line-height: 1.65;
}

.rumor-r {
  color: var(--ink-soft);
}

.rumor-t {
  color: var(--moon);
  margin-top: 12px !important;
  padding-top: 12px;
  border-top: 1px solid var(--line-soft);
}

.rumor .tag {
  display: inline-block;
  margin-right: 9px;
  padding: 3px 10px;
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: .64rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  white-space: nowrap;
}

.rumor-r .tag {
  color: var(--crimson-2);
  background: rgba(216, 50, 74, .12);
}

.rumor-t .tag {
  color: var(--gold-2);
  background: rgba(216, 171, 90, .12);
}

/* 圖卡為 3:4 直式長圖，收在固定高度的視窗裡，點擊開新分頁看完整原圖 */
.rumor .shot {
  display: block;
  position: relative;
  margin-top: auto;
  height: 380px;
  overflow: hidden;
  cursor: zoom-in;
  border-top: 1px solid var(--line);
  background: var(--bg-2);
}

.rumor .shot img {
  width: 100%;
  height: auto;
  display: block;
  transition: transform .5s var(--ease);
}

.rumor .shot:hover img {
  transform: scale(1.02);
}

.rumor .shot::after {
  content: "⤢";
  position: absolute;
  right: 12px;
  bottom: 12px;
  width: 30px;
  height: 30px;
  z-index: 2;
  display: grid;
  place-items: center;
  border-radius: 999px;
  font-size: .82rem;
  color: var(--moon);
  background: rgba(11, 12, 16, .72);
  border: 1px solid var(--line);
}

/* 底部漸層提示「還有更多內容，點開來看」 */
.rumor .shot::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 90px;
  z-index: 1;
  background: linear-gradient(transparent, var(--panel));
  pointer-events: none;
}

.rumor-src {
  margin-top: 26px;
  font-family: var(--font-sans);
  font-size: .8rem;
  color: var(--ink-mute);
  text-align: center;
}

/* ---------- Lightbox 圖片彈窗（由 main.js 動態插入，全站共用） ---------- */
.lb {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
}

.lb.open {
  display: block;
}

.lb-veil {
  position: absolute;
  inset: 0;
  background: rgba(6, 7, 10, .88);
}

/* 圖卡是 3:4 長圖，放不下時在這層捲動；點空白處關閉 */
.lb-stage {
  position: absolute;
  inset: 0;
  overflow: auto;
  overscroll-behavior: contain;
  padding: 62px 16px 78px;
  display: flex;
  justify-content: center;
  align-items: flex-start;
}

.lb-stage img {
  display: block;
  width: min(880px, 92vw);
  height: auto;
  border-radius: 12px;
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
}

.lb-btn {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  flex: 0 0 auto;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(20, 22, 30, .92);
  color: var(--moon);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  transition: border-color .2s, color .2s;
}

.lb-btn:hover {
  border-color: var(--gold);
  color: var(--gold-2);
}

.lb-close {
  position: absolute;
  top: 14px;
  right: 16px;
  z-index: 3;
}

/* 控制列會壓在（白底的）圖卡上，所以底色要夠實，不能只靠漸層 */
.lb-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  padding: 14px 16px;
  display: flex;
  gap: 14px;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  font-family: var(--font-sans);
  font-size: .82rem;
  color: var(--ink);
  background: linear-gradient(rgba(6, 7, 10, 0), rgba(6, 7, 10, .92) 34%, rgba(6, 7, 10, .97));
}

.lb-count {
  min-width: 62px;
  text-align: center;
  letter-spacing: .08em;
  color: var(--ink-soft);
}

.lb-raw {
  color: var(--gold-2);
  border-bottom: 1px solid rgba(216, 171, 90, .35);
  padding-bottom: 1px;
}

.lb-raw:hover {
  color: var(--moon);
}

body.lb-lock {
  overflow: hidden;
}

/* ---------- Share ---------- */
.share {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: center;
  margin-top: 22px;
}

.share .sbtn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-sans);
  font-size: .82rem;
  padding: 11px 18px;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--ink-soft);
  cursor: pointer;
  background: var(--panel);
  transition: all .2s;
}

.share .sbtn:hover {
  border-color: var(--gold);
  color: var(--moon);
  transform: translateY(-2px);
}

.hashtags {
  margin-top: 16px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.hashtags span {
  font-family: var(--font-sans);
  font-size: .78rem;
  color: var(--gold-2);
  background: rgba(216, 171, 90, .08);
  padding: 5px 12px;
  border-radius: 999px;
}

/* ---------- Callout ---------- */
.callout {
  border-left: 3px solid var(--crimson);
  background: rgba(216, 50, 74, .05);
  padding: 20px 24px;
  border-radius: 0 12px 12px 0;
  margin: 22px 0;
  color: var(--ink-soft);
}

.callout.gold {
  border-color: var(--gold);
  background: rgba(216, 171, 90, .05);
}

/* ---------- 友站連結（首頁）---------- */
/* 一站一個 .callout 直式堆疊時，兩張卡加上大按鈕與一行裸網址會吃掉快一個
   螢幕高度，所以改成並排的緊湊卡片：整張卡可點，網址收進卡片不再另外列出。 */
.partners-label {
  display: block;
  margin-bottom: 12px;
  font-family: var(--font-sans);
  font-size: .68rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--gold);
}

.partners {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
}

.partner {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--gold);
  border-radius: 0 12px 12px 0;
  background: rgba(216, 171, 90, .05);
  color: var(--ink-soft);
  transition: transform .25s var(--ease), border-color .25s, background .25s;
}

/* color 要寫死：整張卡是 <a>，不然全站的 a:hover（變紅）會蓋掉 .partner 的
   顏色，介紹文字沒有自己的 color 就會跟著整段變紅字。 */
.partner:hover {
  transform: translateY(-2px);
  border-color: rgba(216, 171, 90, .45);
  border-left-color: var(--gold-2);
  background: rgba(216, 171, 90, .09);
  color: var(--ink-soft);
}

.partner-name {
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: var(--moon);
  line-height: 1.45;
}

.partner-desc {
  margin: 0;
  font-size: .84rem;
  line-height: 1.7;
  color: var(--ink-soft);
}

/* margin-top:auto 把「前往」壓在卡片底部，兩張卡的介紹長度不同也能對齊 */
.partner-go {
  margin-top: auto;
  padding-top: 4px;
  font-family: var(--font-sans);
  font-size: .76rem;
  letter-spacing: .04em;
  color: var(--gold-2);
}

.partner:hover .partner-go {
  color: var(--moon);
}

/* ---------- Notice (open letter) ---------- */
.notice-block {
  border-top: 0;
  padding: 34px 0 8px;
}

.notice {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 22px;
  background: linear-gradient(160deg, var(--panel), var(--bg-2));
  padding: clamp(30px, 4.5vw, 50px);
  box-shadow: var(--shadow);
}

.notice::before {
  content: "";
  position: absolute;
  right: -70px;
  top: -90px;
  width: 280px;
  height: 280px;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle at 42% 42%, rgba(238, 241, 250, .11), transparent 68%);
}

.notice::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  opacity: .55;
}

.notice .eyebrow {
  display: block;
}

.notice h3 {
  position: relative;
  font-size: clamp(1.35rem, 3vw, 1.7rem);
  color: var(--moon);
  margin: 14px 0 20px;
}

.notice p {
  position: relative;
  color: var(--ink-soft);
  white-space: pre-line;
  margin: 0;
  max-width: 62ch;
  line-height: 1.95;
}

/* ---------- Footer ---------- */
footer {
  border-top: 1px solid var(--line-soft);
  padding: 50px 0 60px;
  margin-top: 40px;
}

.foot-grid {
  display: flex;
  justify-content: space-between;
  gap: 30px;
  flex-wrap: wrap;
}

.foot-grid .brand {
  margin-bottom: 12px;
}

footer p {
  color: var(--ink-mute);
  font-size: .84rem;
  max-width: 520px;
  line-height: 1.7;
}

.disclaimer {
  margin-top: 24px;
  padding-top: 22px;
  border-top: 1px solid var(--line-soft);
  font-size: .78rem;
  color: var(--ink-mute);
}

/* 頁尾導覽：四欄分組。單欄排 14 條會拉出一根比左邊高好幾倍的長柱，中間留一大片空白。
   ⚠ 這裡不能用 auto-fit：.foot-nav 是 .foot-grid（flex）的子項，寬度由內容決定，
   auto-fit 拿不到確定的容器寬度，會直接退回單欄——等於沒改。欄數要寫死，
   窄畫面再用斷點收成兩欄。 */
.foot-nav {
  display: grid;
  grid-template-columns: repeat(4, max-content);
  gap: 4px 38px;
}

.foot-col strong {
  display: block;
  margin-bottom: 6px;
  font-family: var(--font-sans);
  font-size: .72rem;
  letter-spacing: .2em;
  color: var(--ink-mute);
  text-transform: uppercase;
}

.foot-nav a {
  display: block;
  font-family: var(--font-sans);
  font-size: .84rem;
  color: var(--ink-soft);
  padding: 4px 0;
}

/* 聲援總部：上方導覽把它獨立出來當主要入口，頁尾比照辦理，不塞進四組裡 */
.foot-hq {
  display: inline-block;
  margin-top: 14px;
  padding-bottom: 2px;
  font-family: var(--font-sans);
  font-size: .84rem;
  color: var(--gold-2);
  border-bottom: 1px solid rgba(216, 171, 90, .35);
}

.foot-hq:hover {
  color: var(--moon);
  border-bottom-color: rgba(216, 171, 90, .7);
}

/* ---------- 活動時間閘門（實體周邊到期自動下架） ---------- */
.merch-ended {
  display: none;
}

#merchGate.expired .merch-live {
  display: none;
}

#merchGate.expired .merch-ended {
  display: block;
}

/* ---------- SPA 內容過場 ---------- */
#app {
  transition: opacity .2s var(--ease);
}

body.is-navigating #app {
  opacity: .3;
}

/* ---------- 常駐主題曲播放器 ---------- */
.music-fab {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 0;
  background: rgba(18, 20, 28, .9);
  backdrop-filter: blur(12px) saturate(1.2);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 7px;
  cursor: pointer;
  box-shadow: var(--shadow);
  transition: border-color .3s var(--ease), transform .3s var(--ease);
  overflow: hidden;
  user-select: none;
  /* <button> 的原生外觀要清掉，字體顏色要繼承 */
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  color: inherit;
  text-align: left;
  /* 手機：關掉 300ms 雙擊縮放延遲與灰色點擊高亮 */
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

/* hover 只給真的有滑鼠的裝置。
   iOS Safari 會有「黏著 hover」：第一次點只會套上 hover（把面板展開），
   不會觸發 click，使用者就會覺得「點了沒反應」，得再點第二次。 */
@media (hover: hover) and (pointer: fine) {
  .music-fab:hover {
    border-color: var(--gold);
    transform: translateY(-2px);
  }
}

/* 觸控時給立即回饋，避免以為沒點到 */
.music-fab:active {
  transform: scale(.94);
  transition-duration: .08s;
}

.music-fab:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

.music-fab .disc {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  flex: 0 0 auto;
  position: relative;
  background: radial-gradient(circle at 38% 34%, #fbfcff 0%, #dfe4f0 26%, #aeb6c8 60%, #7d8496 100%);
  box-shadow: inset -5px -4px 12px rgba(20, 24, 38, .6), inset 4px 3px 9px rgba(255, 255, 255, .4);
  display: grid;
  place-items: center;
}

.music-fab .disc::after {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #14161e;
}

.music-fab.playing .disc {
  animation: mf-spin 7s linear infinite;
}

@keyframes mf-spin {
  to {
    transform: rotate(360deg);
  }
}

.music-fab .mf-text {
  display: flex;
  align-items: center;
  gap: 9px;
  max-width: 0;
  opacity: 0;
  white-space: nowrap;
  font-family: var(--font-sans);
  font-size: .8rem;
  letter-spacing: .04em;
  color: var(--ink-soft);
  transition: max-width .4s var(--ease), opacity .3s var(--ease), padding .4s var(--ease);
}

.music-fab.playing .mf-text {
  max-width: 240px;
  opacity: 1;
  padding: 0 14px 0 11px;
}

@media (hover: hover) and (pointer: fine) {
  .music-fab:hover .mf-text {
    max-width: 240px;
    opacity: 1;
    padding: 0 14px 0 11px;
  }
}

.music-fab .mf-title {
  color: var(--gold-2);
  font-family: var(--font-display);
  letter-spacing: .05em;
}

.music-fab .eq {
  display: inline-flex;
  gap: 2px;
  align-items: flex-end;
  height: 15px;
}

.music-fab .eq i {
  width: 3px;
  height: 4px;
  border-radius: 2px;
  background: var(--gold-2);
}

.music-fab.playing .eq i {
  animation: mf-eq .9s ease-in-out infinite;
}

.music-fab.playing .eq i:nth-child(2) {
  animation-delay: .18s;
}

.music-fab.playing .eq i:nth-child(3) {
  animation-delay: .36s;
}

.music-fab.playing .eq i:nth-child(4) {
  animation-delay: .54s;
}

@keyframes mf-eq {

  0%,
  100% {
    height: 4px;
  }

  50% {
    height: 15px;
  }
}

.music-fab .mf-state {
  color: var(--ink-mute);
  font-size: .9rem;
}

.music-fab.playing .mf-state {
  color: var(--gold-2);
}

@media (prefers-reduced-motion: reduce) {

  .music-fab.playing .disc,
  .music-fab.playing .eq i {
    animation: none;
  }
}

/* 手機：離下緣遠一點。iOS Safari 的網址列/工具列就貼在畫面底部，
   太靠邊的點擊常被瀏覽器 UI 吃掉，或變成「叫出工具列」的手勢。
   env() 在沒有 viewport-fit=cover 時回 0，當作額外保險不影響現況。 */
@media (max-width: 560px) {
  .music-fab {
    right: 14px;
    bottom: calc(26px + env(safe-area-inset-bottom, 0px));
  }
}

/* ---------- Reveal animation ---------- */
[data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}

[data-reveal].in {
  opacity: 1;
  transform: none;
}

/* ---------- Responsive ---------- */
/* 導覽列已改為統一下拉選單，桌機與手機共用同一套樣式，不再需要斷點切換。 */
@media (max-width: 560px) {

  /* 小螢幕：下拉面板改為近乎滿版，較好點按；選單鈕僅留圖示以節省空間 */
  .nav-links {
    left: 0;
    right: 0;
    min-width: 0;
  }

  .nav-toggle .nav-toggle-label {
    display: none;
  }

  .nav-toggle {
    padding: 8px 11px;
  }

  .nav-inner {
    gap: 8px;
    padding: 0 16px;
  }

  .brand {
    font-size: .98rem;
    letter-spacing: .1em;
    gap: 9px;
  }

  .brand>span>span {
    display: none;
  }

  /* 隱藏「· 敖尹」副標以節省寬度 */
  .lang-select {
    padding: 7px 26px 7px 11px;
    font-size: .74rem;
  }
}

@media (max-width: 860px) {
  .stats {
    grid-template-columns: repeat(2, 1fr);
  }

  .grid.cols-3,
  .grid.cols-2,
  .wall,
  .rumors,
  .partners {
    grid-template-columns: 1fr;
  }

  .split,
  .dodont {
    grid-template-columns: 1fr;
  }

  .split .claim {
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }

  .prow {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  .hero-moon {
    width: 300px;
    height: 300px;
    right: -80px;
    top: 20px;
    opacity: .5;
  }

  .foot-grid {
    flex-direction: column;
  }

  /* 收成一欄的話又會變回那根長柱，所以窄畫面仍然保留兩欄。
     用 minmax(0,max-content) 而不是 1fr：1fr 會把兩欄撐到容器兩端、中間空一大片；
     minmax 的下限給 0 是保險，萬一某個語言的標籤特別長，欄位可以縮而不是把版面撐破。 */
  .foot-nav {
    grid-template-columns: repeat(2, minmax(0, max-content));
    justify-content: start;
    gap: 4px 44px;
  }
}

@media (max-width: 460px) {
  .stats {
    grid-template-columns: 1fr;
  }
}

/* =========================================================================
   給敖尹的話 — 腳印小徑（voices.html）
   放在全站樣式表而不是該頁的 <style>，是因為 main.js 的 SPA 路由換頁時
   只抽換 #app、不會換 <head>；寫在頁面裡的話從導覽列點進去就沒有樣式。
   ========================================================================= */
#voiceStage {
  position: relative;
  height: clamp(380px, 58vh, 580px);
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  background: #07080c;
  /* 拖曳要吃得到，所以關掉瀏覽器自己的平移手勢；游標明示這裡可以拖 */
  touch-action: none;
  cursor: grab;
  user-select: none;
}

#voiceStage.panning {
  cursor: grabbing;
}

/* 全部塞得進畫面時沒東西可拖，游標就不要騙人 */
#voiceStage.nopan {
  cursor: default;
}

#voiceStage:focus-visible {
  outline: 2px solid var(--gold-2);
  outline-offset: 2px;
}

#voiceCanvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* 數量：不做排行也不做熱門，就只是「現在有幾枚」 */
#voiceMeta {
  position: absolute;
  top: 14px;
  left: 16px;
  pointer-events: none;
  font-family: var(--font-sans);
  font-size: .72rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

#voiceMeta b {
  font-family: var(--font-display);
  font-size: 1.5rem;
  color: var(--gold-2);
  letter-spacing: 0;
  display: block;
  line-height: 1.1;
}

/* 空的/讀不到時的說明，壓在正中間 */
#voiceState {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 28px;
  text-align: center;
  color: var(--ink-soft);
  font-size: .9rem;
  line-height: 1.8;
}

/* 預覽模式徽章（?demo=N），順便顯示即時 fps */
/* 開發用徽章。原本在右上角，二維改版後那裡讓給迷你地圖了，所以移到左下。 */
#voiceStage .vc-demo {
  position: absolute;
  bottom: 14px;
  left: 16px;
  z-index: 2;
  padding: 5px 10px;
  pointer-events: none;
  border: 1px solid rgba(216, 50, 74, .5);
  border-radius: 999px;
  background: rgba(216, 50, 74, .14);
  font-family: var(--font-sans);
  font-size: .68rem;
  letter-spacing: .08em;
  color: #ec526a;
}

/* 點到某一枚腳印時浮出來的那句話 */
#voiceCard {
  position: absolute;
  left: 50%;
  bottom: 18px;
  transform: translate(-50%, 10px);
  width: min(420px, calc(100% - 32px));
  padding: 14px 18px;
  border: 1px solid rgba(240, 211, 140, .32);
  border-radius: 12px;
  background: rgba(12, 14, 20, .94);
  box-shadow: var(--shadow);
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s var(--ease), transform .25s var(--ease);
}

#voiceCard.on {
  opacity: 1;
  transform: translate(-50%, 0);
}

#voiceCard .vc-msg {
  margin: 0;
  color: var(--ink);
  font-size: .95rem;
  line-height: 1.75;
}

#voiceCard .vc-by {
  display: block;
  margin-top: 8px;
  font-family: var(--font-sans);
  font-size: .72rem;
  color: var(--ink-mute);
  letter-spacing: .06em;
}

/* ---- 敖尹的回話 ----
   進到這一頁時，他說的那一句。整頁只有一個，跟任何一則留言都不綁定
   （為什麼，見 voices.html 上面那段註解）。

   刻意走暖金、留言卡走冷灰：不用讀字就分得出「這句是他說的」。
   左邊那道金色細邊是整塊的重心——沒有它，這就只是又一張灰卡片，
   會直接被當成導言的一部分滑過去。 */
#voiceReply {
  display: flex;
  gap: 13px;
  align-items: flex-start;
  margin-top: 24px;
  padding: 15px 20px 16px;
  border: 1px solid rgba(240, 211, 140, .28);
  border-left: 3px solid var(--gold);
  border-radius: 4px 12px 12px 4px;
  background: linear-gradient(100deg, rgba(56, 44, 24, .55), rgba(20, 22, 30, .55) 62%);
}

#voiceReply[hidden] {
  display: none;
}

#voiceReply .vr-paw {
  width: 19px;
  height: 21px;
  flex: 0 0 auto;
  margin-top: 2px;
  fill: var(--gold-2);
  opacity: .85;
}

#voiceReply .vr-body {
  min-width: 0;
}

#voiceReply .vr-who {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin-bottom: 7px;
  font-family: var(--font-sans);
  line-height: 1.4;
}

#voiceReply .vr-who b {
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .12em;
  color: var(--gold-2);
}

/* 「今天，從林子深處傳來的聲音」——這行有兩個工作，都不是裝飾：
   一是防呆，講明白這句話不是誰寫給誰的回信，才不會有人以為自己剛留的那句
   得到了回覆；二是預告，讓人知道明天回來聽到的會是別的一句。 */
#voiceReply .vr-who i {
  font-style: normal;
  font-size: .7rem;
  letter-spacing: .04em;
  color: var(--ink-mute);
}

#voiceReply .vr-msg {
  margin: 0;
  color: #f5ebd6;
  font-size: 1rem;
  line-height: 1.85;
}

@media (max-width:520px) {
  #voiceReply {
    gap: 10px;
    padding: 13px 15px 14px;
    margin-top: 20px;
  }

  #voiceReply .vr-paw {
    width: 17px;
    height: 19px;
  }

  #voiceReply .vr-msg {
    font-size: .94rem;
    line-height: 1.8;
  }
}

/* 迷你地圖。取代原本那條一維的位置指示器：1433 則時可見範圍只佔世界的 5.2%，
   那顆滑塊卻寫死 18% 寬，拖再久都幾乎不動。二維之後世界接近正方形，
   縮圖才讀得懂。尺寸由 JS 依世界長寬比算出來寫進 canvas，這裡只管外框和位置。 */
#voiceMap {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 2;
  padding: 5px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(6, 8, 12, .88);
  cursor: crosshair;
  touch-action: none;
  line-height: 0;
  /* 舞台整體是 grab 游標、卡片是 pointer-events:none，地圖要自己收事件 */
  pointer-events: auto;
}

#voiceMap[hidden] {
  display: none;
}

#voiceMap canvas {
  display: block;
  border-radius: 4px;
}

/* 手機上舞台本來就矮，地圖收小一點，不要把林地擋掉 */
@media (max-width:520px) {
  #voiceMap {
    top: 10px;
    right: 10px;
    padding: 4px;
  }

  #voiceMap canvas {
    max-width: 88px;
    max-height: 88px;
  }
}

#voiceHint {
  margin-top: 10px;
  text-align: center;
  font-size: .78rem;
  color: var(--ink-mute);
}

/* ---- 投稿框 ---- */
#voiceCompose[hidden] {
  display: none;
}

#voiceCompose textarea,
#voiceCompose input {
  width: 100%;
  font-family: var(--font-sans);
  font-size: .92rem;
  line-height: 1.7;
  color: var(--ink);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
  resize: none;
}

#voiceCompose textarea::placeholder,
#voiceCompose input::placeholder {
  color: var(--ink-mute);
}

#voiceCompose textarea:focus,
#voiceCompose input:focus {
  outline: 2px solid rgba(240, 211, 140, .5);
  outline-offset: 1px;
  border-color: transparent;
}

#voiceCompose .vc-row {
  display: flex;
  gap: 10px;
  margin-top: 10px;
  align-items: stretch;
}

#voiceCompose .vc-row input {
  flex: 1;
  min-width: 0;
}

/* 語言選單。和暱稱、送出鈕擠同一行——投稿框是在「留一句話」的情緒裡，
   多一行欄位就多一分表單感。窄螢幕靠 flex-wrap 自己換行，不另外寫 media query。 */
#voiceCompose .vc-row {
  flex-wrap: wrap;
}

/* 原生 <select> 每個平台長得都不一樣（macOS 會是一顆亮色的系統控制項），
   所以拿掉原生外觀、自己畫箭頭，這樣六種語言在哪台機器上都是同一個樣子。 */
.vc-langpick {
  flex: 0 0 auto;
  padding: 0 32px 0 13px;
  border: 1px solid var(--line);
  border-radius: 10px;
  -webkit-appearance: none;
  appearance: none;
  background-color: var(--bg-2);
  color: var(--ink-soft);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23aab0c0' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 10px 6px;
  font-family: var(--font-sans);
  font-size: .86rem;
  cursor: pointer;
}

.vc-langpick:focus {
  outline: 2px solid rgba(240, 211, 140, .5);
  outline-offset: 1px;
  border-color: transparent;
}

#voiceCompose .vc-row .btn {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* 成功和失敗共用同一行，靠 class 換顏色；沒訊息時不佔高度 */
#voiceCompose .vc-result {
  margin: 10px 0 0;
  font-size: .82rem;
  line-height: 1.7;
  color: var(--ink-soft);
}

#voiceCompose .vc-result:empty {
  display: none;
}

#voiceCompose .vc-result.err {
  color: var(--crimson-2);
}

/* 剩餘字數：疊在輸入框右下角，快滿了才出現，平常不干擾 */
#voiceCompose .vc-field {
  position: relative;
}

#voiceCompose .vc-left {
  position: absolute;
  right: 10px;
  bottom: 8px;
  pointer-events: none;
  font-family: var(--font-sans);
  font-size: .72rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-mute);
}

#voiceCompose .vc-left.low {
  color: var(--crimson-2);
  font-weight: 700;
}

/* canvas 對螢幕閱讀器等於一片空白，所以另外掛一份看不見的純文字清單 */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion:reduce) {
  #voiceCard {
    transition: none;
  }
}

/* ---- 毛絮牆：絨毛/列表切換 ---- */
/* 切換鈕和搜尋框同一排。窄螢幕放不下就換行，搜尋框自己撐滿。 */
.vc-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

.vc-views {
  display: flex;
  gap: 2px;
  padding: 3px;
  width: max-content;
  flex: 0 0 auto;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg-2);
}

/* ---- 搜尋 ---- */
.vc-find {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1 1 220px;
  min-width: 0;
}

/* 語言篩選。沒有任何一則帶語言資料時，JS 會把外層的 <span> 收起來。 */
.vc-lang[hidden] {
  display: none;
}

.vc-find select {
  flex: 0 0 auto;
  padding: 7px 28px 7px 13px;
  border: 1px solid var(--line);
  border-radius: 999px;
  -webkit-appearance: none;
  appearance: none;
  background-color: var(--bg-2);
  color: var(--ink-soft);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23aab0c0' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  background-size: 9px 5px;
  font-family: var(--font-sans);
  font-size: .78rem;
  cursor: pointer;
}

.vc-find select:focus {
  outline: 2px solid rgba(240, 211, 140, .45);
  outline-offset: 1px;
}

.vc-find input {
  /* 上限 360：不設的話它會撐滿整條，桌機上變成一個很空的長槽，
     而且「N 筆符合」會被推到最右邊，離輸入框太遠讀不到一起。 */
  flex: 1 1 auto;
  min-width: 0;
  max-width: 360px;
  padding: 7px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg-2);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: .82rem;
}

.vc-find input::placeholder {
  color: var(--ink-mute);
}

.vc-find input:focus {
  outline: 2px solid rgba(240, 211, 140, .45);
  outline-offset: 1px;
  border-color: transparent;
}

/* Safari 的 type=search 會自己長一顆叉叉，和圓角外框對不齊 */
.vc-find input::-webkit-search-decoration,
.vc-find input::-webkit-search-cancel-button {
  -webkit-appearance: none;
}

.vc-find-out {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  font-family: var(--font-sans);
  font-size: .76rem;
  color: var(--ink-mute);
  white-space: nowrap;
}

.vc-find-out[hidden] {
  display: none;
}

.vc-find-out b {
  color: var(--crimson-2);
  font-variant-numeric: tabular-nums;
}

.vc-find-out b:empty {
  display: none;
}

.vc-find-nav {
  display: flex;
  gap: 2px;
}

.vc-find-nav[hidden] {
  display: none;
}

.vc-find-nav button {
  width: 24px;
  height: 24px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg-2);
  color: var(--ink-soft);
  font-size: .9rem;
  line-height: 1;
  cursor: pointer;
  transition: color .2s var(--ease), border-color .2s var(--ease);
}

.vc-find-nav button:hover {
  color: var(--gold-2);
  border-color: rgba(240, 211, 140, .4);
}

/* 搜尋時被藏起來的那幾則 */
#voiceList li[hidden] {
  display: none;
}

.vc-views button {
  padding: 6px 18px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font-family: var(--font-sans);
  font-size: .76rem;
  letter-spacing: .06em;
  color: var(--ink-mute);
  cursor: pointer;
  transition: color .2s var(--ease), background .2s var(--ease);
}

.vc-views button:hover {
  color: var(--ink-soft);
}

.vc-views button.on {
  background: var(--panel-2);
  color: var(--gold-2);
}

/* 列表模式。同一份 <ul> 兩種身分：腳印模式時掛上 .sr-only 給螢幕閱讀器用，
   列表模式時拿掉就變成看得見的內容——不必維護兩份 DOM。 */
#voiceList:not(.sr-only) {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
  max-height: min(70vh, 620px);
  overflow-y: auto;
  padding-right: 6px;
}

#voiceList:not(.sr-only) li {
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
}

#voiceList:not(.sr-only) .vl-msg {
  margin: 0;
  color: var(--ink);
  font-size: .95rem;
  line-height: 1.75;
}

#voiceList:not(.sr-only) .vl-by {
  display: block;
  margin-top: 7px;
  font-family: var(--font-sans);
  font-size: .72rem;
  letter-spacing: .06em;
  color: var(--ink-mute);
}

/* 捲軸細一點，不要在暗底上砸出一條白槓 */
#voiceList:not(.sr-only)::-webkit-scrollbar {
  width: 6px;
}

#voiceList:not(.sr-only)::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: 999px;
}

/* 蜜罐欄位。用「移出畫面」而不是 display:none，因為部分機器人會跳過
   display:none 的欄位——移出畫面它們仍然會填，我們才抓得到。 */
.vc-hp {
  position: absolute !important;
  left: -9999px !important;
  top: auto !important;
  width: 1px !important;
  height: 1px !important;
  opacity: 0 !important;
  pointer-events: none !important;
}

/* 送出中的轉圈。用 currentColor 畫，所以套在任何按鈕上顏色都會自己對。
   減少動態偏好開啟時不轉，但環還在——文字已經寫著「送出中…」，
   靜止的環仍然是一個「有事情在進行」的訊號。 */
.sending::before {
  content: "";
  display: inline-block;
  width: .78em;
  height: .78em;
  margin-right: .5em;
  vertical-align: -.08em;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: vc-spin .7s linear infinite;
}

@keyframes vc-spin {
  to {
    transform: rotate(360deg)
  }
}

@media (prefers-reduced-motion:reduce) {
  .sending::before {
    animation: none;
    opacity: .6;
  }
}

/* =========================================================================
   頭貼框工具（frame.html）
   桌機左右兩欄（預覽固定在左、控制項在右），≤760px 收成上下一欄。
   ========================================================================= */
.fm {
  display: grid;
  grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
  gap: 30px;
  align-items: start;
  margin-top: 8px;
}

/* 移出畫面而不是 display:none——後者在部分行動版瀏覽器上按了叫不出檔案選擇器 */
.fm-file,
.ch-file {
  position: absolute !important;
  left: -9999px !important;
  width: 1px !important;
  height: 1px !important;
  opacity: 0 !important;
}

/* ---- 舞台 ---- */
.fm-stage {
  position: relative;
}

/* canvas 與上傳區的共同外框。高度由 canvas 決定，上傳區才有東西可以貼齊。 */
.fm-canvas-wrap {
  position: relative;
  line-height: 0;
}

/* 預覽刻意保持正方形、不用 border-radius 切成圓：
   輸出就是一張正方形 PNG，四個角是它的一部分。用 CSS 把角切掉的話，
   底色改了在預覽上看不出來，使用者要等到存檔打開才知道自己選了什麼。 */
#fmCanvas {
  display: block;
  width: 100%;
  aspect-ratio: 1/1;
  border-radius: 12px;
  background: var(--bg-2);
  border: 1px solid transparent;
  /* 空狀態的框由上傳區的虛線負責 */
  touch-action: none;
  /* 交給 pointer 事件自己處理平移縮放 */
  cursor: default;
  outline: none;
  border-radius: 100%;
}

.fm-stage.has-img #fmCanvas {
  cursor: grab;
  border-color: var(--line-soft);
}

.fm-stage.has-img #fmCanvas.grabbing {
  cursor: grabbing;
}

#fmCanvas:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 4px;
}

/* 沒選圖時蓋在 canvas 上；選了圖就讓開（含滑鼠事件）。
   幾何要對齊 canvas 的框：用 inset:0 會連底下的說明文字一起蓋進去，
   高度變大、border-radius:50% 就會畫出一個比 canvas 還大的橢圓。 */
.fm-drop {
  /* inset:0 貼齊 .fm-canvas-wrap，也就是 canvas 本身的框。
     不要用 aspect-ratio 推算高度：那只是「偏好」尺寸，實機 Safari 上不一定生效，
     一失效就退回內容高度，變成一顆比畫布扁、而且中心偏上的橢圓。 */
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 9px;
  text-align: center;
  cursor: pointer;
  transition: background .2s var(--ease);
  border-radius: 100%;
  /* 不畫虛線圈：它跟畫布同一個半徑，正好被聲援框的環蓋住，看不見；
     內縮又會壓到環。手機也沒有拖放這回事，這條線本來就沒在傳達什麼。
     「這裡可以放照片」交給 ＋ 和文字說，拖曳回饋交給底色。 */
  /* 內距用百分比、不用固定 px：這一塊是圓的，內容必須留在圓裡面，
     而圓的可用寬度隨元件寬度變。 */
  padding: 12%;
  /* 保險絲：某個語言的文字特別長時，寧可裁掉也不要頂破這顆圓。 */
  overflow: hidden;
}

.fm-stage.has-img .fm-drop {
  display: none;
}

.fm-drop:hover,
.fm-stage.over .fm-drop {
  background: rgba(216, 171, 90, .06);
}

.fm-drop:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

.fm-drop-ic {
  font-size: 1.5rem;
  line-height: 1;
  color: var(--gold-2);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  border: 1px solid rgba(216, 171, 90, .4);
  margin-bottom: 4px;
}

.fm-drop b {
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: var(--moon);
  letter-spacing: .04em;
}

.fm-drop em {
  font-style: normal;
  font-family: var(--font-sans);
  font-size: .74rem;
  color: var(--ink-mute);
  line-height: 1.6;
}

/* 小螢幕（≤350px）的圓變小，但聲援框那圈字的寬度是按比例的，
   可用的內圈半徑只剩約 97px——實測中/日/西語的提示會差幾 px 壓到框上。
   這裡把上傳區的內容整組縮一號，讓最遠角退回安全半徑內。 */
@media (max-width:350px) {
  .fm-drop {
    padding: 10%;
  }

  .fm-drop-ic {
    width: 38px;
    height: 38px;
    font-size: 1.25rem;
    margin-bottom: 2px;
  }

  .fm-drop b {
    font-size: .95rem;
  }

  .fm-drop em {
    font-size: .66rem;
  }
}

.fm-tip {
  margin: 12px 0 0;
  text-align: center;
  font-family: var(--font-sans);
  font-size: .74rem;
  letter-spacing: .06em;
  color: var(--ink-mute);
}

.fm-stage:not(.has-img) .fm-tip {
  opacity: 0;
}

/* ---- 控制面板 ---- */
.fm-label {
  display: block;
  margin: 22px 0 9px;
  font-family: var(--font-sans);
  font-size: .68rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--gold);
}

.fm-label i {
  font-style: normal;
  color: var(--ink-soft);
  letter-spacing: .04em;
}

.fm-panel>.fm-row:first-child .fm-label {
  margin-top: 0;
}

.fm-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.fm-wide {
  width: 100%;
  justify-content: center;
}

.fm-actions {
  margin-top: 26px;
}

.fm-actions .btn {
  flex: 1 1 auto;
  justify-content: center;
  text-align: center;
}

.btn[disabled] {
  opacity: .4;
  pointer-events: none;
}

/* min-width:0 不能省：格線軌道預設是 minmax(auto,…)，
   裡面有不換行的橫捲列時，軌道會被撐到比畫面還寬，整頁跟著橫向溢出。 */
.fm-panel {
  min-width: 0;
}

/* 框的縮圖列。桌機換行（六款一次看得完），窄螢幕再改成橫向捲動。 */
.fm-frames {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  min-width: 0;
}

.fm-chip {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 78px;
  padding: 8px 4px;
  cursor: pointer;
  background: none;
  border: 1px solid transparent;
  border-radius: 14px;
  font-family: var(--font-sans);
  font-size: .68rem;
  line-height: 1.3;
  color: var(--ink-mute);
  text-align: center;
  transition: border-color .18s, color .18s, background .18s;
}

.fm-chip img {
  border-radius: 50%;
  display: block;
}

.fm-chip span {
  display: block;
  word-break: break-word;
}

.fm-chip:hover {
  color: var(--ink-soft);
  background: rgba(255, 255, 255, .04);
}

.fm-chip.on {
  border-color: rgba(216, 171, 90, .55);
  color: var(--gold-2);
  background: rgba(216, 171, 90, .07);
}

/* 貼紙縮圖：SVG 本身多半是亮色，直接放在深底上會看不清邊界，所以墊一塊面板色 */
.fm-chip-st img {
  border-radius: 12px;
  background: var(--panel-2);
  padding: 5px;
  box-sizing: content-box;
}

.fm-chip-none {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  padding: 5px;
  border-radius: 12px;
  background: var(--panel-2);
  color: var(--ink-mute);
}

#fmStRow[hidden] {
  display: none;
}

/* 貼紙微調的方向鍵。排成十字，按鈕本身就說明了自己往哪走。 */
.fm-pad {
  display: grid;
  grid-template-columns: repeat(3, 36px);
  grid-template-rows: repeat(3, 36px);
  gap: 6px;
  justify-content: start;
}

/* 滑桿。原生外觀在深底上幾乎看不見，所以整個重畫。 */
.fm-range {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 3px;
  background: var(--line);
  border-radius: 999px;
  outline: none;
  cursor: pointer;
}

.fm-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background: linear-gradient(140deg, var(--gold-2), var(--gold));
  border: 1px solid rgba(11, 12, 16, .5);
  cursor: grab;
}

.fm-range::-moz-range-thumb {
  width: 17px;
  height: 17px;
  border-radius: 50%;
  border: 1px solid rgba(11, 12, 16, .5);
  background: linear-gradient(140deg, var(--gold-2), var(--gold));
  cursor: grab;
}

.fm-range:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 6px;
}

.fm-note {
  margin: 8px 0 0;
  font-family: var(--font-sans);
  font-size: .74rem;
  line-height: 1.6;
  color: var(--ink-mute);
}

/* 底色色票 */
.fm-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  align-items: center;
}

.fm-sw {
  width: 30px;
  height: 30px;
  flex: 0 0 auto;
  padding: 0;
  cursor: pointer;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--sw, transparent);
  transition: transform .15s var(--ease), border-color .15s, box-shadow .15s;
}

.fm-sw:hover {
  transform: scale(1.08);
  border-color: var(--steel);
}

.fm-sw.on {
  border-color: var(--gold);
  box-shadow: 0 0 0 2px rgba(216, 171, 90, .28);
}

.fm-sw:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

/* 自訂色：固定顯示色環。
   刻意「不」把它畫成目前選的顏色——那樣色票列會出現兩個一模一樣的圈，
   分不出哪個才是選中的。這一格是「開啟選色器」這個動作，不是顏色預覽。 */
.fm-sw-custom {
  position: relative;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: conic-gradient(#d8324a, #d8ab5a, #8fd6a6, #6fb6e8, #a98fe8, #d8324a);
}

.fm-sw-custom input[type="color"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  opacity: 0;
  cursor: pointer;
}

/* 成品。手機不觸發下載，改把圖片放這裡讓使用者長按存檔。 */
.fm-result[hidden] {
  display: none;
}

.fm-result {
  margin-top: 24px;
}

.fm-result img {
  display: block;
  width: 100%;
  max-width: 240px;
  margin: 0 auto;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--bg-2);
}

.fm-result .fm-note {
  text-align: center;
}

.fm-msg {
  min-height: 1.4em;
  margin: 12px 0 0;
  font-family: var(--font-sans);
  font-size: .8rem;
  color: var(--ink-mute);
}

.fm-msg.warn {
  color: var(--crimson-2);
}

@media (max-width:760px) {
  .fm {
    grid-template-columns: minmax(0, 1fr);
    gap: 22px;
  }

  /* width:100% 不能省。這是 grid item，而 `margin:0 auto` 會取消格線預設的
     stretch，寬度就退回「內容寬度」——內容是 canvas，它的原生預設寬度是 300px。
     結果預覽固定 302px、控制項 323px，兩邊左右差 11px 對不齊。 */
  .fm-stage {
    width: 100%;
    max-width: 340px;
    margin: 0 auto;
  }

  .fm-actions .btn {
    flex: 1 1 100%;
  }

  /* 聲援框維持左右滑動 */
  #fmFrames {
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: 6px;
    scrollbar-width: thin;
  }

  /* 貼紙改成自動換行，不產生左右捲動 */
  #fmStickers {
    flex-wrap: wrap;
    overflow-x: visible;
    padding-bottom: 0;
  }
}

/* ---------- 聲援圖（frame.html 下方）---------- */
/* 現成的社群貼文圖。點圖走全站共用的燈箱，右邊給一個直接下載的連結——
   手機上下載常常不可靠，長按存圖才是通用做法，所以說明文字兩種都講。 */
.support-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  margin-top: 6px;
}

.support-item {
  margin: 0;
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  transition: border-color .3s var(--ease);
}

.support-item:hover {
  border-color: rgba(216, 171, 90, .4);
}

.support-shot {
  display: block;
  line-height: 0;
  cursor: zoom-in;
}

.support-item img {
  width: 100%;
  height: auto;
  display: block;
  transition: transform .5s var(--ease);
}

.support-item:hover img {
  transform: scale(1.03);
}

.support-cap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 9px 12px;
  border-top: 1px solid var(--line-soft);
  font-family: var(--font-sans);
  font-size: .8rem;
  color: var(--ink-soft);
}

.support-dl {
  flex: 0 0 auto;
  white-space: nowrap;
  font-size: .76rem;
  letter-spacing: .04em;
  color: var(--gold-2);
}

.support-dl:hover {
  color: var(--moon);
}

@media (max-width:760px) {
  .support-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
  }

  .support-cap {
    padding: 8px 10px;
    font-size: .74rem;
  }

  .support-dl {
    font-size: .72rem;
  }
}

/* ---------- 電視牆應援卡（billboards.html）---------- */
/* 來源是微博規格的直式長圖（最長的一張原比例 1:4.3），整張塞進版面會變成
   一條看不懂的細長帶。所以卡片只放「主視覺 4:5 裁切」，完整長圖走燈箱——
   燈箱本來就會捲動，長圖在那裡才讀得完。 */
.screens {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 18px;
  margin-top: 6px;
}

.screen {
  margin: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  transition: border-color .3s var(--ease), transform .3s var(--ease);
}

.screen:hover {
  border-color: rgba(216, 171, 90, .4);
  transform: translateY(-3px);
}

.screen-shot {
  display: block;
  position: relative;
  line-height: 0;
  cursor: zoom-in;
  aspect-ratio: 4/5;
  overflow: hidden;
}

.screen-shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .5s var(--ease);
}

.screen:hover .screen-shot img {
  transform: scale(1.04);
}

/* 城市名不壓在圖上：宣傳圖自己就印著「敖尹○○七夕大屏」，疊上去會直接撞字 */
.screen-city {
  display: block;
  margin: 0 0 2px;
  font-family: var(--font-display);
  font-size: 1.24rem;
  line-height: 1.2;
  color: var(--moon);
}

.screen-city small {
  display: block;
  margin-top: 4px;
  font-family: var(--font-sans);
  font-size: .64rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gold-2);
}

.screen-body {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 15px 16px 16px;
  flex: 1;
}

.screen-meta {
  margin: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 6px 10px;
}

.screen-meta dt {
  font-family: var(--font-sans);
  font-size: .68rem;
  letter-spacing: .16em;
  color: var(--gold);
  white-space: nowrap;
  padding-top: .28em;
}

.screen-meta dd {
  margin: 0;
  font-size: .88rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

.screen-meta dd b {
  color: var(--ink);
  font-weight: 600;
}

/* 原文簡體地址：給地圖 App 搜尋用的，繁中轉寫在中國地圖上常常搜不到 */
.screen-raw {
  font-family: var(--font-sans);
  font-size: .76rem;
  color: var(--ink-mute);
  word-break: break-all;
}

.screen-tag {
  align-self: flex-start;
  margin-top: auto;
  padding: 3px 9px;
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: .66rem;
  letter-spacing: .12em;
  color: var(--gold-2);
  background: rgba(216, 171, 90, .1);
  border: 1px solid rgba(216, 171, 90, .3);
}

.screen-more {
  font-family: var(--font-sans);
  font-size: .78rem;
  letter-spacing: .04em;
  color: var(--gold-2);
  border-bottom: 1px solid rgba(216, 171, 90, .35);
  align-self: flex-start;
  padding-bottom: 1px;
}

.screen-more:hover {
  color: var(--moon);
}

@media (max-width:520px) {
  .screens {
    grid-template-columns: 1fr;
  }
}

/* =========================================================================
   封存橫幅 —— 限時活動結束後，頁面留下來但要一眼看出「這是紀錄，不是進行中」
   （relay.html / billboards.html。兩頁已從導覽移除，只留舊網址與站內回顧連結）
   ========================================================================= */
.archived {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  flex-wrap: wrap;
  margin: 0 0 26px;
  padding: 18px 22px;
  border-radius: 12px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--steel);
  background: linear-gradient(90deg, rgba(174, 182, 198, .07), rgba(174, 182, 198, .02));
  color: var(--ink-soft);
}

.archived-badge {
  flex: 0 0 auto;
  align-self: center;
  padding: 4px 11px;
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: .66rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--steel);
  background: rgba(174, 182, 198, .1);
  border: 1px solid rgba(174, 182, 198, .32);
  white-space: nowrap;
}

.archived-body {
  flex: 1 1 260px;
  min-width: 0;
}

.archived-body h3 {
  margin: 0 0 6px;
  font-size: 1.05rem;
  color: var(--moon);
}

.archived-body p {
  margin: 0;
  font-size: .92rem;
}

.archived-body .btn-row {
  margin-top: 14px;
}

/* =========================================================================
   七夕接力作品牆（relay-works.html）
   卡片是 X 的官方嵌入，高度由對方的 iframe 決定，所以用 grid + align-items:start，
   不用 column（iframe 會被欄位切斷）。排不滿的下緣參差是刻意接受的代價。
   ========================================================================= */
.rw-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 14px;
  margin: 22px 0 6px;
}

.rw-stat {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-2);
  padding: 18px 14px;
  text-align: center;
}

.rw-stat .v {
  font-family: var(--font-display);
  font-size: 2rem;
  line-height: 1;
  color: var(--gold-2);
}

.rw-stat .k {
  font-family: var(--font-sans);
  font-size: .68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-top: 9px;
}

.rw-wall {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  align-items: start;
  gap: 20px;
  margin-top: 6px;
}

/* 佔位高度：X 的嵌入卡片大約 400–700px，未載入的文字卡只有 ~150px。
   不預留空間的話有兩個後果：捲下去時整個版面不斷往下暴衝（layout shift），
   而且延遲載入會失效——一百多張矮卡片會全部落在 IntersectionObserver 的
   rootMargin 範圍內，等於一次全開，就白做了。載好之後（或確定載不到時）撤掉。 */
.rw-item {
  margin: 0;
  min-width: 0;
  min-height: 420px;
}

.rw-item:has(.twitter-tweet-rendered) {
  min-height: 0;
}

.rw-wrap.is-blocked .rw-item {
  min-height: 0;
}

.rw-item .twitter-tweet {
  margin: 0 !important;
}

/* 還沒被 widgets.js 換掉的 blockquote —— 也就是 X 載不進來時使用者實際看到的東西。
   牆內/擋追蹤器的讀者只會有這個，所以它必須自己就是一張說得清楚的卡片，
   不能是一段裸引文。widgets.js 成功時整個 blockquote 會被換成 div.twitter-tweet-rendered，
   選擇器指定 blockquote 就不會影響到已轉換的卡片。 */
.rw-wall blockquote.twitter-tweet {
  display: block;
  border: 1px solid var(--line);
  border-left: 3px solid var(--gold);
  border-radius: 0 12px 12px 0;
  background: var(--bg-2);
  padding: 16px 18px;
  font-size: .95rem;
  color: var(--ink-soft);
}

.rw-wall blockquote.twitter-tweet .rw-title {
  display: block;
  margin: 0 0 8px;
  font-size: 1.02rem;
  color: var(--moon);
  line-height: 1.5;
}

.rw-wall blockquote.twitter-tweet .rw-by {
  display: block;
  font-family: var(--font-sans);
  font-size: .8rem;
  letter-spacing: .04em;
  color: var(--ink-mute);
}

.rw-wall blockquote.twitter-tweet a {
  display: inline-block;
  margin-top: 12px;
  font-family: var(--font-sans);
  font-size: .8rem;
  letter-spacing: .04em;
  color: var(--gold-2);
  border-bottom: 1px solid rgba(216, 171, 90, .35);
  padding-bottom: 1px;
}

.rw-wall blockquote.twitter-tweet a:hover {
  color: var(--moon);
}

.rw-day {
  display: inline-block;
  margin-bottom: 10px;
  padding: 3px 9px;
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: .64rem;
  letter-spacing: .12em;
  color: var(--steel);
  background: rgba(174, 182, 198, .1);
  border: 1px solid rgba(174, 182, 198, .28);
}

/* 被 X 擋掉、改用本站授權副本顯示的那幾棒。
   卡片是本站的 <img>，不是 iframe，所以不需要 .rw-item 的 420px 佔位高度
   （那個佔位是為了讓延遲載入的 X 嵌入不塌陷）。 */
.rw-item--rescued {
  min-height: 0;
}

.rw-rescued {
  border: 1px solid var(--line);
  border-left: 3px solid var(--gold);
  border-radius: 0 12px 12px 0;
  background: var(--bg-2);
  overflow: hidden;
}

.rw-rescued-shot {
  display: block;
}

/* height:auto 不能省——沒有它，HTML 的 height 屬性會把圖壓成固定高度 */
.rw-rescued-shot img {
  display: block;
  width: 100%;
  height: auto;
}

.rw-rescued-by {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 12px 16px 0;
  font-family: var(--font-sans);
}

.rw-rescued-by .rw-day {
  margin-bottom: 0;
}

.rw-rescued-by .rw-by {
  font-size: .8rem;
  letter-spacing: .04em;
  color: var(--ink-mute);
}

.rw-rescued-note {
  margin: 8px 0 0;
  padding: 0 16px;
  font-size: .78rem;
  line-height: 1.5;
  color: var(--ink-mute);
}

/* 「在 X 上觀看」。上面那條 .rw-wall blockquote.twitter-tweet a 只吃 blockquote 裡的連結，
   救回的卡片不是 blockquote，所以樣式要在這裡自己給一份。 */
.rw-rescued .rw-open {
  display: inline-block;
  margin: 10px 16px 14px;
  font-family: var(--font-sans);
  font-size: .8rem;
  letter-spacing: .04em;
  color: var(--gold-2);
  border-bottom: 1px solid rgba(216, 171, 90, .35);
  padding-bottom: 1px;
}

.rw-rescued .rw-open:hover {
  color: var(--moon);
}

/* 分批顯示的「載入更多」 */
.rw-more-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-top: 30px;
}

.rw-more-row[hidden] {
  display: none;
}

.rw-more-n {
  margin-left: 8px;
  font-family: var(--font-sans);
  font-size: .8rem;
  color: var(--gold-2);
}

.rw-shown {
  margin: 0;
  font-family: var(--font-sans);
  font-size: .76rem;
  letter-spacing: .14em;
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
}

.rw-wrap.is-empty .rw-more-row {
  display: none;
}

/* 載入中/載不到的提示。預設兩個都不顯示，由 relay-works.js 掛 class 決定。 */
.rw-note {
  display: none;
}

.rw-wrap.is-loading .rw-note--loading {
  display: block;
}

.rw-wrap.is-blocked .rw-note--blocked {
  display: block;
}

.rw-wrap.is-empty .rw-note--empty {
  display: block;
}

.rw-wrap.is-empty .rw-wall,
.rw-wrap.is-empty .rw-stats {
  display: none;
}

@media (max-width:520px) {
  .rw-wall {
    grid-template-columns: 1fr;
  }

  .archived {
    padding: 16px 18px;
  }
}

/* =========================================================================
   七夕接力作品牆 · 小紅書場（relay-xhs.html）
   跟上面那面牆的差別在資料來源：這裡是本站自存的圖檔，不是別人的 iframe，
   所以沒有「載不到」的狀態、也不需要佔位高度（圖片自己帶 width/height）。

   ⚠ 用 grid，不要改成 columns 做瀑布流。
     瀑布流是先填滿第一欄再填第二欄，讀者由上往下看到的會是 #1 #2 #3…#16
     全部擠在左邊一直行——接力的棒次順序就毀了。grid 是由左到右依序排，
     代價是每張圖高度不同、下緣參差，這是刻意接受的。
     另一條路是把圖裁成統一比例，但那是裁切他人的作品，不做。
   ========================================================================= */
.rx-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 14px;
  margin: 22px 0 6px;
}

.rx-stat {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-2);
  padding: 18px 14px;
  text-align: center;
}

.rx-stat .v {
  font-family: var(--font-display);
  font-size: 2rem;
  line-height: 1;
  color: var(--gold-2);
}

.rx-stat .k {
  font-family: var(--font-sans);
  font-size: .68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-top: 9px;
}

.rx-wall {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  align-items: start;
  gap: 20px;
  margin-top: 6px;
}

.rx-item {
  margin: 0;
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-2);
  overflow: hidden;
}

.rx-stat[hidden] {
  display: none;
}

.rx-shot {
  display: block;
}

/* 影片用原生播放器，不進燈箱（燈箱是把 href 塞進 <img>，影片會變破圖）。
   底色給黑：preload="none" 時未播放的區塊由 poster 撐著，
   萬一某支沒配到封面，黑底也比透明的破框體面。 */
.rx-video {
  display: block;
  width: 100%;
  height: auto;
  background: #000;
}

/* 圖片帶著建置時讀到的 width/height，這裡只負責等比縮放。
   height:auto 不能省——沒有它，HTML 的 height 屬性會把圖壓成固定高度。 */
.rx-shot img {
  display: block;
  width: 100%;
  height: auto;
}

/* 封面之後的圖：小方縮圖排成一列。小紅書的筆記常常是 4～9 張的圖文集，
   全部照原比例堆下去的話一棒就佔掉一整個螢幕，整面牆會參差到看不出接力順序。
   縮圖用 cover 裁切，但點開燈箱看到的一律是完整原圖。 */
/* auto-fit 而不是 auto-fill：兩者的差別在「欄位不夠填滿時怎麼辦」。
   auto-fill 會留著空欄位，只有 2 張縮圖時右邊就空一大片；
   auto-fit 把空欄位收掉、讓現有縮圖平分寬度，2 張就是各佔一半。 */
.rx-extras {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
  gap: 2px;
  border-top: 1px solid var(--line);
}

.rx-shot--extra img {
  aspect-ratio: 1/1;
  object-fit: cover;
}

.rx-by {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 12px 14px;
  border-top: 1px solid var(--line);
  font-family: var(--font-sans);
  font-size: .84rem;
}

.rx-n {
  flex: none;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: .64rem;
  letter-spacing: .1em;
  font-variant-numeric: tabular-nums;
  color: var(--steel);
  background: rgba(174, 182, 198, .1);
  border: 1px solid rgba(174, 182, 198, .28);
}

.rx-artist {
  color: var(--moon);
  border-bottom: 1px solid rgba(216, 171, 90, .35);
  padding-bottom: 1px;
  overflow-wrap: anywhere;
  /* 暱稱可能很長，別把卡片撐破 */
}

.rx-artist:hover {
  color: var(--gold-2);
}

.rx-note {
  margin-left: auto;
  flex: none;
  font-size: .74rem;
  letter-spacing: .06em;
  color: var(--gold-2);
  border-bottom: 1px solid rgba(216, 171, 90, .35);
  padding-bottom: 1px;
}

.rx-note:hover {
  color: var(--moon);
}

/* 分批顯示的「載入更多」 */
.rx-more-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-top: 30px;
}

.rx-more-row[hidden] {
  display: none;
}

.rx-more-n {
  margin-left: 8px;
  font-family: var(--font-sans);
  font-size: .8rem;
  color: var(--gold-2);
}

.rx-shown {
  margin: 0;
  font-family: var(--font-sans);
  font-size: .76rem;
  letter-spacing: .14em;
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
}

.rx-wrap.is-empty .rx-more-row {
  display: none;
}

/* 「還在整理」的提示。預設不顯示，由 relay-xhs.js 掛 class 決定。 */
.rx-note-box {
  display: none;
}

.rx-wrap.is-empty .rx-note-box--empty {
  display: block;
}

.rx-wrap.is-empty .rx-wall,
.rx-wrap.is-empty .rx-stats {
  display: none;
}

@media (max-width:520px) {
  .rx-wall {
    grid-template-columns: 1fr;
  }
}

/* =========================================================================
   30 Little Things for Valko（challenge.html）
   放在全站樣式表而不是該頁的 <style>，理由和腳印林地一樣：
   main.js 的 SPA 路由換頁時只抽換 #app、不會換 <head>，
   寫在頁面裡的話從導覽列點進去就沒有樣式。
   ========================================================================= */

/* ---- 挑戰規則 ----
   放在盤面之前：每一格都要交一張照片，這件事必須在人開始點格子以前就知道，
   不然他會勾了五格才發現自己沒有東西可以交。 */
.ch-rules {
  margin-top: 26px;
  padding: 20px 22px 22px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--gold);
  border-radius: 4px 16px 16px 4px;
  background: linear-gradient(100deg, rgba(56, 44, 24, .34), rgba(20, 22, 30, .4) 60%);
}

.ch-rules h3 {
  margin: 0 0 12px;
  font-family: var(--font-sans);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .18em;
  color: var(--gold);
}

/* 編號自己畫成圓形徽章：預設的 ::marker 在換行時對不齊，
   七條規則排下來會像一段被硬切開的文字，讀不進去。 */
.ch-rules ol {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: chrule;
}

.ch-rules li {
  position: relative;
  counter-increment: chrule;
  margin: 0 0 14px;
  padding-left: 38px;
  font-size: .88rem;
  line-height: 1.9;
  color: var(--ink-soft);
}

.ch-rules li:last-child {
  margin-bottom: 0;
}

.ch-rules li::before {
  content: counter(chrule);
  position: absolute;
  left: 0;
  top: .25em;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(240, 211, 140, .35);
  background: rgba(240, 211, 140, .08);
  font-family: var(--font-sans);
  font-size: .72rem;
  font-variant-numeric: tabular-nums;
  color: var(--gold-2);
}

.ch-rules strong {
  color: var(--gold-2);
  font-weight: 600;
}

/* 最後一條是這個活動真正的規則：曝光的節奏比完成速度重要。 */
.ch-rule-key {
  color: var(--ink) !important;
}

/* 「資料會不見」那條用顏色講，不用 emoji——
   一個 ⚠️ 夾在整齊的編號清單裡，看起來像別人貼上去的。 */
.ch-rule-warn {
  color: var(--ink) !important;
}

.ch-rule-warn::before {
  border-color: rgba(236, 82, 106, .5) !important;
  background: rgba(236, 82, 106, .12) !important;
  color: var(--crimson-2) !important;
}

.ch-rule-warn strong {
  color: var(--crimson-2);
}

/* ---- 卡面區 ----
   左邊是賓果盤（看得出連線、截圖好看），右邊是「月亮」進度。
   兩件事分開放的理由：盤面回答「我連到哪了」，月亮回答「我走了多遠」——
   同一塊地方擠著回答兩個問題，兩個都看不清楚。 */
.ch-head {
  margin-top: 24px;
}

.ch-hero {
  display: grid;
  gap: 26px;
  align-items: stretch;
  /* 兩張卡等高並排 */
  grid-template-columns: minmax(0, 380px) minmax(0, 1fr);
}

@media (max-width:720px) {
  .ch-hero {
    grid-template-columns: 1fr;
    gap: 22px;
  }
}

/* ---- 賓果盤 ----
   格子裡只放題號，題目在下面那份清單裡——最長的題目有二十八個字，
   塞進小方格會擠到讀不了，而手機上五欄的話每欄只剩七十像素。
   所以盤面負責「看得到全貌、看得出連線、截圖好看」，清單負責讀題和勾選。 */

/* 一張真的卡：外框 ＋ BINGO 欄頭。
   沒有這一層的話，三十個圓角方塊看起來只是一排按鈕，不是賓果卡。 */
.ch-card {
  padding: 14px 14px 16px;
  border: 1px solid rgba(240, 211, 140, .28);
  border-radius: 18px;
  background:
    radial-gradient(120% 90% at 78% -10%, rgba(240, 211, 140, .14), transparent 60%),
    linear-gradient(180deg, rgba(30, 26, 20, .75), rgba(16, 18, 24, .75));
  box-shadow: var(--shadow);
}

.ch-bingo {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 6px;
  margin-bottom: 10px;
}

.ch-bingo span {
  text-align: center;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--gold-2);
  opacity: .85;
}

.ch-board {
  display: grid;
  grid-template-columns: repeat(var(--cols, 5), 1fr);
  gap: 6px;
}

/* 格子本身只是底座；勾選的印章畫在裡面那個 <span> 上，
   ::before / ::after 留給橫線和直線。 */
.ch-cell {
  position: relative;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(8, 10, 14, .5);
  cursor: pointer;
  user-select: none;
}

.ch-cell:hover {
  border-color: rgba(240, 211, 140, .4);
}

.ch-num {
  position: relative;
  z-index: 2;
  width: 74%;
  aspect-ratio: 1;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: .74rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-mute);
  transition: background .18s var(--ease), color .18s var(--ease);
}

/* 勾起來＝蓋一個圓形的印章，不是把整格塗滿。
   方格塗滿看起來像「選取中」，圓形印章才像賓果的墨戳。 */
/* 印章是一枚狼爪。圓形的金色圓點只是「選取中」的通用語言，
   爪印是這個站的——小狼走過的地方。四趾＋掌墊全是橢圓，
   縮到手機上那顆五十幾像素的格子裡還認得出形狀，
   換成鈴蘭那種有莖有葉的圖形就會糊成一團。
   題號往下擠到掌墊上（padding-top 讓內容中心落在 68% 高的地方）。 */
.ch-cell.on .ch-num {
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cg fill='%23f0d38c'%3E%3Cellipse cx='22' cy='42' rx='11' ry='14' transform='rotate(-20 22 42)'/%3E%3Cellipse cx='40' cy='26' rx='11' ry='15' transform='rotate(-8 40 26)'/%3E%3Cellipse cx='62' cy='26' rx='11' ry='15' transform='rotate(8 62 26)'/%3E%3Cellipse cx='80' cy='42' rx='11' ry='14' transform='rotate(20 80 42)'/%3E%3Cellipse cx='51' cy='70' rx='27' ry='23'/%3E%3C/g%3E%3C/svg%3E") center/104% no-repeat;
  padding-top: 36%;
  color: #3a2c0e;
  font-weight: 700;
  filter: drop-shadow(0 0 9px rgba(240, 211, 140, .5));
}

/* ★ 連成的線真的畫出來 ★
   只把格子塗色的話，使用者看到的是「幾個格子變亮」，不是「連成了一排」。
   線比格子寬 14px（gap 是 6px），所以會跨過格子之間的縫隙連成一整條。

   不用粗的實心線：那看起來像被人拿紅筆劃掉。改成一條細的發光絲線，
   從爪印底下穿過去，讀起來是「把它們串起來」而不是「畫掉它們」。 */
.ch-cell::before,
.ch-cell::after {
  /* z-index 1＝走在爪印底下。壓在上面的話會把印章切成兩半，
     而爪印是「這一格做過了」的唯一標記，不能犧牲。 */
  content: "";
  position: absolute;
  z-index: 1;
  pointer-events: none;
  border-radius: 3px;
  opacity: 0;
  background: linear-gradient(var(--dir, 90deg),
      rgba(236, 82, 106, .35), #ec526a 35%, #ff7d92 50%, #ec526a 65%, rgba(236, 82, 106, .35));
  box-shadow: 0 0 9px rgba(236, 82, 106, .75), 0 0 20px rgba(236, 82, 106, .3);
}

.ch-cell::before {
  left: -7px;
  right: -7px;
  top: 50%;
  height: 3px;
  margin-top: -1.5px;
  transform: scaleX(0);
  transform-origin: left center;
}

.ch-cell::after {
  top: -7px;
  bottom: -7px;
  left: 50%;
  width: 3px;
  margin-left: -1.5px;
  --dir: 180deg;
  transform: scaleY(0);
  transform-origin: center top;
}

.ch-cell.lh::before {
  opacity: 1;
  transform: scaleX(1);
}

.ch-cell.lv::after {
  opacity: 1;
  transform: scaleY(1);
}

/* 一格一格延遲，線就像被「畫」過去的，而不是整條憑空出現。
   --col / --row 由 challenge.js 在建盤面時寫進每一格。 */
@media (prefers-reduced-motion:no-preference) {
  .ch-cell::before {
    transition: transform .34s var(--ease) calc(var(--col, 0) * .07s),
      opacity .16s linear calc(var(--col, 0) * .07s);
  }

  .ch-cell::after {
    transition: transform .34s var(--ease) calc(var(--row, 0) * .07s),
      opacity .16s linear calc(var(--row, 0) * .07s);
  }

  /* 線掃過去的時候，爪印跟著彈一下——連成一排是這張卡唯一的「成就時刻」，
     值得有個動作。 */
  .ch-cell.lh .ch-num {
    animation: chPop .5s var(--ease) calc(var(--col, 0) * .07s) both;
  }

  .ch-cell.lv .ch-num {
    animation: chPop .5s var(--ease) calc(var(--row, 0) * .07s) both;
  }

  @keyframes chPop {
    0% {
      transform: scale(1)
    }

    45% {
      transform: scale(1.16);
      filter: drop-shadow(0 0 14px rgba(240, 211, 140, .85))
    }

    100% {
      transform: scale(1)
    }
  }
}

/* ---- 狀態面板 ----
   進度條會告訴你「62%」，但沒有人為了一條長方形再回來一次。
   月亮會：它從新月一路盈到滿月，而這個活動本來就跨到中秋
   （第 29、30 格是中秋限定）。同一個數字，換一個看得下去的形狀。

   月亮和數字包在一張與盤面等高的面板裡、內容置中——
   單獨擺在右邊那一塊空白裡，怎麼調位置都像沒放好。 */
.ch-panel {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 26px 22px;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: 18px;
  background:
    radial-gradient(120% 90% at 50% -20%, rgba(240, 211, 140, .10), transparent 62%),
    linear-gradient(180deg, var(--panel), rgba(16, 18, 24, .55));
}

.ch-side {
  display: flex;
  flex-direction: column;
}

.ch-moon {
  position: relative;
  flex: 0 0 auto;
  margin-bottom: 16px;
  width: 128px;
  height: 128px;
  border-radius: 50%;
  overflow: hidden;
  background: #171a22;
  box-shadow: 0 0 0 1px rgba(240, 211, 140, .22), 0 0 70px -14px rgba(240, 211, 140, .45);
}

/* 真的月相，不是水位。
   月亮是從右邊亮起來的（北半球），明暗界線是一條橫著掃過去的弧——
   由下往上漲那種是水杯，不是月亮，看的人第一眼就會覺得怪。

   做法是經典的兩層：右半邊先亮起來，再疊一顆會變寬的橢圓當界線——
   還不到上弦時橢圓是暗的（吃掉右半邊 → 眉月），過了上弦換成亮的
   （吃進左半邊 → 盈凸月）。寬度和顏色都由 challenge.js 寫進 CSS 變數。 */
.ch-moon-lit {
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg, #fff6e2, var(--gold-2) 55%, var(--gold));
  clip-path: inset(0 0 0 50%);
}

.ch-moon-term {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: var(--term, 100%);
  transform: translateX(-50%);
  border-radius: 50%;
  background: var(--term-bg, #171a22);
}

@media (prefers-reduced-motion:no-preference) {
  .ch-moon-term {
    transition: width .8s var(--ease), background-color .8s var(--ease);
  }
}

/* 環形山：沒有它就只是一顆黃色的球。壓在填色上面，所以兩邊都看得到。 */
.ch-moon span {
  position: absolute;
  border-radius: 50%;
  background: rgba(120, 92, 40, .32);
}

.ch-moon .cr1 {
  width: 23px;
  height: 23px;
  top: 29px;
  left: 27px;
}

.ch-moon .cr2 {
  width: 13px;
  height: 13px;
  top: 64px;
  left: 72px;
}

.ch-moon .cr3 {
  width: 9px;
  height: 9px;
  top: 89px;
  left: 37px;
}

.ch-count {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 8px;
}

.ch-count b {
  font-family: var(--font-display);
  font-size: 2.8rem;
  line-height: 1.1;
  color: var(--gold-2);
}

.ch-count .ch-total {
  font-family: var(--font-sans);
  font-size: .9rem;
  color: var(--ink-mute);
  letter-spacing: .08em;
}

.ch-count-line {
  margin-top: 12px;
  padding-top: 14px;
  border-top: 1px solid var(--line-soft);
  width: 100%;
}

.ch-count-line b {
  font-size: 1.6rem;
  color: var(--crimson-2);
}

.ch-of {
  font-family: var(--font-sans);
  font-size: .74rem;
  color: var(--ink-mute);
}

.ch-phase {
  margin: 4px 0 0;
  font-family: var(--font-sans);
  font-size: .8rem;
  letter-spacing: .12em;
  color: var(--gold);
}

.ch-cardhint {
  margin: 12px 0 0;
  font-size: .74rem;
  color: var(--ink-mute);
  text-align: center;
}

.ch-state {
  margin: 14px 0 0;
  font-size: .82rem;
  line-height: 1.8;
  color: var(--ink-soft);
  max-width: 30ch;
}

.ch-state:empty {
  display: none;
}

/* ---- 存檔提示 ----
   進度就編在網址裡（六個字元），所以「把網址存起來」＝「把進度存起來」。
   Safari 的 ITP 會在七天沒造訪時自己刪掉 localStorage，這一塊不是裝飾。 */
.ch-save {
  margin-top: 24px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--gold);
  border-radius: 4px 12px 12px 4px;
  background: linear-gradient(100deg, rgba(56, 44, 24, .4), rgba(20, 22, 30, .4) 60%);
}

.ch-save-row {
  display: flex;
  gap: 10px;
  align-items: stretch;
}

.ch-save-row input {
  flex: 1;
  min-width: 0;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-2);
  color: var(--ink-soft);
  font-family: var(--font-sans);
  font-size: .82rem;
}

.ch-save-row .btn {
  flex: 0 0 auto;
  white-space: nowrap;
}

.ch-save-note {
  margin: 10px 0 0;
  font-size: .78rem;
  line-height: 1.8;
  color: var(--ink-mute);
}

/* ---- 六組 ----
   一組就是賓果盤上的一橫排，所以每一組自己是一張卡、右上角自己數 x/5。
   組頭的 x/5 是這裡最實用的一個數字：使用者要湊一條線的時候，
   要找的是「哪一組只差一格」，而那個答案不該讓人自己數。 */
.ch-group {
  margin-top: 16px;
  padding: 15px 16px 17px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: linear-gradient(180deg, var(--panel), rgba(16, 18, 24, .55));
  transition: border-color .25s var(--ease);
}

.ch-group.full {
  border-color: rgba(240, 211, 140, .4);
}

.ch-gh {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 13px;
}

.ch-gem {
  font-size: 1.05rem;
  line-height: 1;
}

.ch-gt {
  font-family: var(--font-sans);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .18em;
  color: var(--gold);
}

.ch-gc {
  margin-left: auto;
  font-family: var(--font-sans);
  font-size: .72rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-mute);
}

.ch-group.full .ch-gc {
  color: var(--gold-2);
}

.ch-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
}

.ch-item {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: rgba(8, 10, 14, .42);
  overflow: hidden;
  transition: border-color .2s var(--ease), transform .2s var(--ease);
}

.ch-item:hover {
  border-color: rgba(240, 211, 140, .3);
}

@media (prefers-reduced-motion:no-preference) {
  .ch-item:hover {
    transform: translateY(-2px);
  }
}

.ch-item:has(.ch-tick.on) {
  border-color: rgba(240, 211, 140, .32);
  background: linear-gradient(160deg, rgba(56, 44, 24, .42), rgba(8, 10, 14, .42) 62%);
}

/* 整格的勾選鈕。用真的 <button>：鍵盤、螢幕閱讀器、
   iOS Safari 的點擊合成全部免費拿到。 */
.ch-tick {
  flex: 1;
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 14px 15px;
  border: 0;
  background: transparent;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.ch-n {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 9px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  background: var(--bg-2);
  font-family: var(--font-sans);
  font-size: .68rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-mute);
  transition: all .2s var(--ease);
}

.ch-t {
  font-size: .9rem;
  line-height: 1.7;
  color: var(--ink-soft);
}

/* 勾起來的樣子。刻意不用刪除線——那讀起來像「作廢」，
   但這些是「做到了」，要看起來是成就不是註銷。 */
/* 清單裡也蓋同一枚爪印（盤面和清單是同一件事的兩個視角，
   兩邊用不同的符號會讓人以為是兩種狀態）。這裡的格子只有 26px，
   再疊題號會糊，所以題號收起來，只留爪印。 */
.ch-tick.on .ch-n {
  border-color: transparent;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cg fill='%23f0d38c'%3E%3Cellipse cx='22' cy='42' rx='11' ry='14' transform='rotate(-20 22 42)'/%3E%3Cellipse cx='40' cy='26' rx='11' ry='15' transform='rotate(-8 40 26)'/%3E%3Cellipse cx='62' cy='26' rx='11' ry='15' transform='rotate(8 62 26)'/%3E%3Cellipse cx='80' cy='42' rx='11' ry='14' transform='rotate(20 80 42)'/%3E%3Cellipse cx='51' cy='70' rx='27' ry='23'/%3E%3C/g%3E%3C/svg%3E") center/92% no-repeat;
  filter: drop-shadow(0 0 8px rgba(240, 211, 140, .45));
  /* font-size:0 是用來蓋掉格子編號那個「文字節點」——它不是元素，
     選不到也 display:none 不掉，只能靠字級把它壓成看不見。 */
  font-size: 0;
}

.ch-tick.on .ch-t {
  color: var(--ink);
}

.ch-tick:focus-visible {
  outline: 2px solid var(--gold-2);
  outline-offset: -2px;
}

/* 從盤面點過來時閃一下：捲到定位之後，使用者要知道「就是這一格」 */
.ch-item:has(.ch-tick.flash) {
  border-color: var(--gold-2);
}

.ch-tick.flash {
  background: rgba(240, 211, 140, .1);
}

@media (prefers-reduced-motion:no-preference) {
  .ch-tick.flash {
    transition: background .3s var(--ease);
  }
}

.ch-go {
  display: block;
  padding: 8px 15px 11px;
  margin-top: -4px;
  font-family: var(--font-sans);
  font-size: .74rem;
  letter-spacing: .06em;
  color: var(--ink-mute);
  text-decoration: none;
}

.ch-go:hover {
  color: var(--gold-2);
}

/* ---- 打卡彈窗 ----
   點一格不是直接打勾，是開這張表：一格＝一則貼文，而貼文的連結和截圖
   就是在這裡收的。直接勾掉的話，使用者永遠沒有一個「順手把連結貼上」的時機。 */
.ch-modal[hidden] {
  display: none;
}

.ch-modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.ch-modal-veil {
  position: absolute;
  inset: 0;
  background: rgba(6, 7, 10, .82);
  backdrop-filter: blur(4px);
}

.ch-sheet {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 540px;
  max-height: 90vh;
  overflow: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 22px 22px 0 0;
  box-shadow: var(--shadow);
  padding: 22px 20px calc(22px + env(safe-area-inset-bottom));
}

@media (min-width:600px) {
  .ch-modal {
    align-items: center;
    padding: 20px;
  }

  .ch-sheet {
    border-radius: 22px;
  }
}

@media (prefers-reduced-motion:no-preference) {
  .ch-sheet {
    animation: chUp .26s var(--ease);
  }

  @keyframes chUp {
    from {
      transform: translateY(22px);
      opacity: 0
    }

    to {
      transform: none;
      opacity: 1
    }
  }
}

.ch-sheet-tag {
  display: inline-block;
  margin-bottom: 12px;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-2);
  font-family: var(--font-sans);
  font-size: .72rem;
  letter-spacing: .06em;
  color: var(--gold);
}

.ch-sheet h3 {
  margin: 0 0 18px;
  font-size: 1.12rem;
  line-height: 1.6;
}

.ch-field {
  margin-bottom: 16px;
}

.ch-field label {
  display: block;
  margin-bottom: 7px;
  font-family: var(--font-sans);
  font-size: .78rem;
  color: var(--ink-mute);
}

.ch-field input[type=text],
.ch-field input[type=url] {
  width: 100%;
  padding: 10px 13px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-2);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: .88rem;
}

.ch-field input[type=text]:focus,
.ch-field input[type=url]:focus {
  outline: none;
  border-color: var(--gold-2);
}

.ch-field textarea {
  width: 100%;
  padding: 10px 13px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-2);
  color: var(--ink);
  resize: vertical;
  font-family: var(--font-body);
  font-size: .92rem;
  line-height: 1.7;
}

.ch-field textarea:focus {
  outline: none;
  border-color: var(--gold-2);
}

.ch-shot-pick {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.ch-shot-pick .btn {
  padding: 8px 18px;
  font-size: .78rem;
}

.ch-shot-name {
  font-family: var(--font-sans);
  font-size: .74rem;
  color: var(--ink-mute);
}

.ch-hint {
  margin: 8px 0 0;
  font-family: var(--font-sans);
  font-size: .72rem;
  line-height: 1.7;
  color: var(--ink-mute);
}

.ch-shot[hidden] {
  display: none;
}

.ch-shot {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  margin-top: 12px;
  flex-wrap: wrap;
}

.ch-shot-prev {
  display: block;
  width: 100%;
  max-width: 200px;
  border-radius: 12px;
  border: 1px solid var(--line);
}

.ch-shot-clear {
  padding: 8px 14px;
  font-size: .78rem;
}

.ch-sheet-btns {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 20px;
}

.ch-sheet-btns .btn {
  flex: 1 1 auto;
  justify-content: center;
}

.ch-sheet-btns .btn[hidden] {
  display: none;
}

.ch-sheet .ch-msg {
  margin-top: 12px;
}

.ch-sheet .ch-out {
  margin-top: 14px;
}

.ch-sheet .ch-out img {
  max-width: 100%;
}

/* ---- 分享圖工具 ----
   暱稱只印在圖上、不進網址：網址是拿來轉貼的，把名字編進去等於每一條
   傳出去的存檔連結都掛著本人的暱稱。 */
.ch-tools {
  margin-top: 24px;
  padding: 16px 18px 18px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: linear-gradient(180deg, var(--panel), rgba(16, 18, 24, .55));
}

.ch-nick {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.ch-nick label {
  font-family: var(--font-sans);
  font-size: .78rem;
  color: var(--ink-mute);
}

.ch-nick input {
  flex: 0 1 220px;
  min-width: 0;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg-2);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: .86rem;
}

.ch-nick input:focus {
  outline: none;
  border-color: var(--gold-2);
}

.ch-msg {
  min-height: 1.4em;
  margin: 12px 0 0;
  font-family: var(--font-sans);
  font-size: .8rem;
  color: var(--ink-mute);
}

.ch-msg.warn {
  color: var(--crimson-2);
}

.ch-out[hidden] {
  display: none;
}

.ch-out {
  margin: 16px 0 0;
}

.ch-out img {
  display: block;
  width: 100%;
  max-width: 360px;
  margin: 0 auto;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--bg-2);
}

.ch-out figcaption {
  margin-top: 10px;
  text-align: center;
  font-family: var(--font-sans);
  font-size: .76rem;
  line-height: 1.7;
  color: var(--ink-mute);
}

/* 下載按鈕是使用者自己按的，不自動觸發：
   手機上自動下載會跳出瀏覽器自己的面板，成功與否使用者完全看不出來。 */
.ch-dl[hidden] {
  display: none;
}

.ch-dl {
  display: block;
  width: max-content;
  margin: 14px auto 0;
}

/* ---- 獎狀 ----
   鎖著的時候按鈕留在原地寫「還差幾格」，不是把它藏起來：
   看得到但還拿不到的東西，比不知道有這東西更會讓人想做完。 */
.ch-cert {
  margin-top: 30px;
  padding: 20px 20px 22px;
  border: 1px solid rgba(240, 211, 140, .32);
  border-radius: 18px;
  background:
    radial-gradient(120% 120% at 85% -20%, rgba(240, 211, 140, .12), transparent 60%),
    linear-gradient(180deg, rgba(30, 26, 20, .6), rgba(16, 18, 24, .6));
}

.ch-cert h3 {
  margin: 0 0 10px;
  font-size: 1.05rem;
  color: var(--gold-2);
}

.ch-cert p {
  margin: 0 0 10px;
  font-size: .86rem;
  line-height: 1.9;
  color: var(--ink-soft);
}

.ch-cert-lead {
  max-width: 62ch;
}

/* 「分享圖要自己留存」是這一段裡唯一會讓人吃虧的規則，
   所以它自己一個框，不跟申請步驟混在一起。 */
.ch-cert-keep {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin: 16px 0 18px !important;
  padding: 12px 14px;
  border: 1px solid rgba(240, 211, 140, .32);
  border-radius: 12px;
  background: rgba(240, 211, 140, .07);
  color: var(--ink) !important;
}

.ch-cert-keep span:first-child {
  color: var(--gold-2);
  line-height: 1.9;
}

.ch-cert-sub {
  margin: 0 0 10px;
  font-family: var(--font-sans);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .18em;
  color: var(--gold);
}

.ch-cert-steps {
  margin: 0 0 16px;
  padding: 0;
  list-style: none;
  counter-reset: chstep;
}

.ch-cert-steps li {
  position: relative;
  counter-increment: chstep;
  margin: 0 0 10px;
  padding-left: 34px;
  font-size: .86rem;
  line-height: 1.9;
  color: var(--ink-soft);
}

.ch-cert-steps li:last-child {
  margin-bottom: 0;
}

.ch-cert-steps li::before {
  content: counter(chstep);
  position: absolute;
  left: 0;
  top: .3em;
  width: 22px;
  height: 22px;
  border-radius: 7px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(100deg, var(--gold), var(--gold-2));
  color: #3a2c0e;
  font-family: var(--font-sans);
  font-size: .7rem;
  font-weight: 700;
}

.ch-cert-mark {
  padding-top: 14px;
  border-top: 1px solid var(--line);
  font-size: .82rem !important;
  color: var(--ink-mute) !important;
}

.ch-cert .btn-row {
  margin-top: 18px;
}

.ch-cert .btn:disabled {
  cursor: not-allowed;
  box-shadow: none;
  background: var(--panel-2);
  color: var(--ink-mute);
  border: 1px solid var(--line);
}

/* .btn 的 display 權重比瀏覽器內建的 [hidden]{display:none} 高，
   少了這一條，表單還沒開放時那顆按鈕照樣會出現。 */
.ch-cert .btn[hidden] {
  display: none;
}

.ch-cert-soon {
  margin: 12px 0 0;
  font-size: .78rem;
  color: var(--ink-mute);
}

/* 還差幾格：不是按鈕，是距離感——看得到距離比不知道還有多遠更會讓人做完 */
.ch-cert-left {
  margin: 12px 0 0 !important;
  font-family: var(--font-sans);
  font-size: .82rem;
  color: var(--ink-mute) !important;
}

.ch-cert-left.is-ready {
  color: var(--gold-2) !important;
}

.ch-cert-soon[hidden] {
  display: none;
}

@media (max-width:420px) {
  .ch-panel {
    padding: 22px 18px;
  }

  .ch-moon {
    width: 104px;
    height: 104px;
  }

  .ch-moon .cr1 {
    width: 19px;
    height: 19px;
    top: 24px;
    left: 22px;
  }

  .ch-moon .cr2 {
    width: 11px;
    height: 11px;
    top: 52px;
    left: 58px;
  }

  .ch-moon .cr3 {
    width: 8px;
    height: 8px;
    top: 72px;
    left: 30px;
  }

  .ch-count b {
    font-size: 2.3rem;
  }
}

/* =========================================================================
   獎狀牆（wall.html）
   放在全站樣式表而不是該頁的 <style>，理由同挑戰卡：
   main.js 的 SPA 路由換頁時只抽換 #app、不會換 <head>。
   ========================================================================= */
.wall-find {
  display: flex;
  gap: 10px;
  align-items: stretch;
  margin-top: 24px;
}

.wall-find input {
  flex: 1;
  min-width: 0;
  padding: 11px 16px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg-2);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: .92rem;
}

.wall-find input:focus {
  outline: none;
  border-color: var(--gold-2);
}

.wall-find input::-webkit-search-decoration,
.wall-find input::-webkit-search-cancel-button {
  -webkit-appearance: none;
}

.wall-find .btn {
  flex: 0 0 auto;
  white-space: nowrap;
}

.wall-stat {
  margin: 14px 0 0;
  font-family: var(--font-sans);
  font-size: .8rem;
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
}

.wall-stat b {
  color: var(--gold-2);
  font-size: 1.05rem;
}

.wall-stat span[hidden] {
  display: none;
}

/* 「看更多」那一列。
   [hidden] 這一條不能省：.btn 的 display 權重比瀏覽器內建的 [hidden]{display:none}
   高，所以 hidden 掛在按鈕上是沒效的——要掛在這一列，並由這條規則真正隱藏它。
   少了它，即使一張都不剩，畫面上還是會留一顆「看更多（0）」。 */
.wall-more-row {
  margin-top: 22px;
}

.wall-more-row[hidden] {
  display: none;
}

.wall-grid {
  list-style: none;
  margin: 22px 0 0;
  padding: 0;
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}

.wall-item {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  background: linear-gradient(180deg, var(--panel), rgba(16, 18, 24, .55));
  transition: border-color .2s var(--ease), transform .2s var(--ease);
}

.wall-item:hover {
  border-color: rgba(240, 211, 140, .32);
}

@media (prefers-reduced-motion:no-preference) {
  .wall-item:hover {
    transform: translateY(-2px);
  }
}

/* 前 50 / 前 10 的框線就是名次本身，不必再多一句話 */
.wall-item.is-top {
  border-color: rgba(240, 211, 140, .34);
}

.wall-item.is-top10 {
  border-color: rgba(240, 211, 140, .6);
  box-shadow: 0 0 34px -14px rgba(240, 211, 140, .55);
}

.wall-shot {
  display: block;
  line-height: 0;
  background: var(--bg-2);
}

.wall-shot img {
  display: block;
  width: 100%;
  height: auto;
}

/* 沒放圖的一樣要有位置——搜尋得到、看得到名次，才算「公布」 */
.wall-shot--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 16/9;
  font-size: 2rem;
  line-height: 1;
  background:
    radial-gradient(120% 90% at 50% 10%, rgba(240, 211, 140, .14), transparent 60%),
    var(--bg-2);
}

/* 兩行兩欄：左上編號、右上名次標記、左下暱稱、右下日期。
   用 flex 排的話長暱稱會把標記擠到第三行去，看起來像壞掉。 */
.wall-meta {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 4px 10px;
  padding: 13px 15px 15px;
}

.wall-no {
  grid-area: 1/1;
}

.wall-badge {
  grid-area: 1/2;
  justify-self: end;
}

.wall-name {
  grid-area: 2/1;
}

.wall-date {
  grid-area: 2/2;
  justify-self: end;
}

.wall-no {
  font-family: var(--font-sans);
  font-size: .72rem;
  letter-spacing: .06em;
  font-variant-numeric: tabular-nums;
  color: var(--ink-mute);
}

.wall-name {
  font-size: .95rem;
  color: var(--ink);
  font-weight: 600;
}

.wall-date {
  font-family: var(--font-sans);
  font-size: .7rem;
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
}

.wall-badge {
  flex: 0 0 auto;
  padding: 3px 10px;
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: .66rem;
  letter-spacing: .08em;
  background: linear-gradient(100deg, var(--gold), var(--gold-2));
  color: #3a2c0e;
  font-weight: 700;
}

.wall-item.is-top10 .wall-badge {
  box-shadow: 0 0 14px -4px rgba(240, 211, 140, .9);
}

.wall-empty[hidden] {
  display: none;
}

.wall-empty {
  margin: 26px 0 0;
  padding: 22px;
  text-align: center;
  border: 1px dashed var(--line);
  border-radius: 16px;
  font-size: .88rem;
  line-height: 1.9;
  color: var(--ink-mute);
}

/* 期間限定框的角標。絕對定位在縮圖右上，所以 .fm-chip 需要 position:relative。 */
.fm-chip{ position:relative; }
.fm-chip-limited{
  position:absolute; top:0; right:2px;
  font-style:normal; font-size:.56rem; letter-spacing:.08em; line-height:1;
  padding:3px 6px; border-radius:999px; white-space:nowrap;
  background:var(--crimson); color:#fff;
  box-shadow:0 0 0 2px var(--panel);       /* 跟底下的縮圖隔開，邊界才清楚 */
}
#fmLimited[hidden]{ display:none; }
