/* ==========================================================================
   连板涨停 —— 界面样式
   红色为主色调。纯手写 CSS，不引入任何前端构建链。

   设计约定
   · 品牌色用 Radix 风格的红阶（brand-*），语义色单独一套（success/warn/danger）
   · 正文区域保持近白底 + 深色字，保证长时间阅读不刺眼；
     红色用在「身份识别」上：侧栏、标题栏、主按钮、未读、重点标记
   · 间距走 4 的倍数；圆角 6/10/14；阴影分 3 级
   ========================================================================== */

:root {
  /* ---- 品牌红阶 ---- */
  --brand-50:  #fff8f8;
  --brand-100: #fff0f0;
  --brand-200: #ffdedf;
  --brand-300: #ffc6c8;
  --brand-400: #f89a9d;
  --brand-500: #e5484d;   /* 主色 */
  --brand-600: #d2373c;   /* hover */
  --brand-700: #b02429;   /* active */
  --brand-800: #8a1a1f;
  --brand-900: #5c1216;
  --brand-950: #2c0d10;

  /* ---- 侧栏（深红） ---- */
  --side-top:    #35141a;
  --side-bottom: #230c10;
  --side-text:   #efd9db;
  --side-muted:  #b08e91;
  --side-hover:  #ffffff14;
  --side-active: var(--brand-600);
  --side-line:   #ffffff1a;

  /* ---- 中性色 ---- */
  --bg:        #ffffff;
  --bg-soft:   #fafafa;
  --bg-sunken: #f4f4f5;
  --border:    #e8e6e7;
  --border-strong: #d8d4d5;
  --text:      #1a1618;
  --text-soft: #494246;
  --text-muted:#857d81;
  /* 链接与空收藏星：深浅两套主题下都要够对比度 */
  --link:        var(--brand-700);
  --link-hover:  var(--brand-800);
  --star-empty:  #cfc9ca;
  --scroll-thumb: #d9d4d5;
  --scroll-thumb-hover: #c4bdbe;
  --border-hover: #c9c2c3;
  --placeholder:  #b3acae;

  /* ---- 语义色 ---- */
  --ok:        #2f9e44;
  --ok-text:   #237032;   /* 绿色文字用更深一档，白底上达到 AA */
  --ok-bg:     #ebfbee;
  --ok-border: #b2f2bb;
  --warn:      #a26a00;
  --warn-bg:   #fff9db;
  --warn-border:#ffe8a3;

  /* ---- 尺寸与层次 ---- */
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-full: 999px;

  --sh-1: 0 1px 2px #0000000a;
  --sh-2: 0 2px 8px #0000000f, 0 1px 2px #0000000a;
  --sh-3: 0 8px 28px #0000001a, 0 2px 6px #0000000f;
  --sh-brand: 0 2px 8px #e5484d33;

  --sidebar-w: 252px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0; height: 100%;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei",
               "PingFang SC", "Hiragino Sans GB", Roboto, sans-serif;
  font-size: 14px; line-height: 1.65; color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); text-decoration: underline; text-underline-offset: 2px; }

h1, h2, h3 { letter-spacing: -.01em; }

::selection { background: var(--brand-200); color: var(--brand-900); }
/* HTML 的 hidden 属性靠 UA 样式表里的 display:none 生效，作者样式只要写了
   display 就会把它盖掉（踩过：设置页那条声音提醒明明 hidden 却一直挂在页面上）。
   这里统一兜住，免得以后每个组件都要自己小心一次。 */
[hidden] { display: none !important; }

/* 键盘 Tab 时必须看得见焦点落在哪里 */
:focus-visible {
  outline: 2px solid var(--brand-500);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* 滚动条：细一点，跟整体风格一致 */
* { scrollbar-width: thin; scrollbar-color: var(--scroll-thumb) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb); border-radius: var(--r-full); border: 3px solid transparent;
  background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); background-clip: content-box; }
*::-webkit-scrollbar-track { background: transparent; }

.layout { display: flex; height: 100vh; overflow: hidden; }

/* ==========================================================================
   侧栏
   ========================================================================== */

.sidebar {
  width: var(--sidebar-w); flex: 0 0 var(--sidebar-w);
  background: linear-gradient(180deg, var(--side-top) 0%, var(--side-bottom) 100%);
  color: var(--side-text);
  display: flex; flex-direction: column; overflow: hidden;
  border-right: 1px solid #00000040;
}

.sidebar-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 16px 16px 14px; border-bottom: 1px solid var(--side-line);
}
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; color: #fff; font-size: 15px; }
.brand-mark {
  width: 26px; height: 26px; flex: 0 0 26px; display: block;
  filter: drop-shadow(0 2px 5px #e5484d45);
}
.brand-mark svg, .brand-mark img { width: 100%; height: 100%; display: block; }
.head-link {
  color: var(--side-muted); font-size: 15px; width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center; border-radius: var(--r-sm);
}
.head-link:hover { color: #fff; background: var(--side-hover); text-decoration: none; }

.nav { padding: 10px 10px 0; }
.nav-item {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; border-radius: var(--r-sm);
  color: var(--side-text); font-size: 13.5px; font-weight: 500;
  transition: background .12s ease;
}
.nav-item:hover { background: var(--side-hover); text-decoration: none; color: #fff; }
.nav-item.is-active { background: var(--brand-600); color: #fff; box-shadow: var(--sh-brand); }

.channel-block { flex: 1; overflow-y: auto; padding: 16px 10px; }
.block-title {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em;
  color: var(--side-muted); padding: 0 10px 8px;
}
.block-link {
  color: var(--side-muted); font-size: 13px; line-height: 1;
  padding: 2px 4px; border-radius: var(--r-sm);
}
.block-link:hover { color: #fff; background: var(--side-hover); text-decoration: none; }
.channel-item {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 10px; border-radius: var(--r-sm);
  color: var(--side-text); font-size: 14px;
  transition: background .12s ease, color .12s ease;
}
.channel-item:hover { background: var(--side-hover); text-decoration: none; color: #fff; }
.channel-item.is-active {
  background: var(--brand-600); color: #fff; font-weight: 600; box-shadow: var(--sh-brand);
}
.channel-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.channel-item .lock { opacity: .55; font-size: 11px; }


.badge {
  background: var(--brand-600); color: #fff; font-size: 11px; font-weight: 700;
  border-radius: var(--r-full); padding: 1px 7px; min-width: 20px; text-align: center;
  box-shadow: var(--sh-brand); line-height: 1.5;
}
.channel-item.is-active .badge { background: #fff; color: var(--brand-700); box-shadow: none; }

/* ---- 频道分组（会员自己设置：特别关注 / 置顶 / 折叠 / 普通） ---- */
.chan-group { margin-bottom: 4px; }
.group-head {
  display: flex; align-items: center; gap: 6px; width: 100%;
  background: none; border: 0; cursor: pointer; text-align: left;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em;
  color: var(--side-muted); padding: 6px 10px; border-radius: var(--r-sm);
  transition: background .12s ease, color .12s ease;
}
.group-head:hover { color: #fff; background: var(--side-hover); }
.group-head.is-static { cursor: default; }
.group-head.is-static:hover { color: var(--side-muted); background: none; }
.group-name { flex: 1; }
.group-caret { font-size: 10px; transition: transform .12s ease; }
.chan-group:not(.is-folded) .group-caret { transform: rotate(90deg); }
.group-badge { text-transform: none; letter-spacing: 0; }
.chan-group.is-folded .group-body { display: none; }
/* 空频道提示：原来是整片留白，分不清「没消息」和「没加载出来」 */
.empty-hint { padding: 48px 20px; text-align: center; }

/* ---- 频道行：链接 + 右侧「⋮」设置入口 ---- */
.channel-row { display: flex; align-items: center; }
.channel-row .channel-item { flex: 1; min-width: 0; }
.chan-more {
  background: none; border: 0; cursor: pointer; color: var(--side-muted);
  font-size: 15px; line-height: 1; padding: 4px 6px; border-radius: var(--r-sm);
  /* 常驻但压暗：只在 hover 时才出现的话，用户根本找不到这个入口 */
  opacity: .35; transition: opacity .12s ease, background .12s ease, color .12s ease;
}
.channel-row:hover .chan-more,
.channel-row.is-active .chan-more,
.chan-more[aria-expanded="true"] { opacity: 1; }
.chan-more:hover { color: #fff; background: var(--side-hover); }

/* 特别关注：左侧红竖条 + 加粗。
   不整行涂色——那会和「正在看」的选中态混在一起，分不清哪个是重点、哪个是当前。 */
.channel-item.is-special { font-weight: 600; box-shadow: inset 3px 0 0 var(--brand-500); }
.channel-item.is-special.is-active {
  box-shadow: inset 3px 0 0 var(--brand-300), var(--sh-brand);
}

/* 连接状态文字：绿色在白底上要够深才达标 */
#conn-state { color: var(--ok-text); }

.sidebar-foot {
  border-top: 1px solid var(--side-line); padding: 12px 16px 16px;
  background: #0000001f;
}
.me { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.me-name { color: #fff; font-weight: 600; font-size: 13px; }
.me-expiry {
  font-size: 11px; color: var(--side-muted); background: #ffffff14;
  padding: 1px 7px; border-radius: var(--r-full);
}
.me-expiry.is-urgent { background: var(--brand-500); color: #fff; }
.foot-links { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 12px; font-size: 12px; }
.foot-links a { color: var(--side-muted); }
.foot-links a:hover { color: #fff; text-decoration: none; }
.inline { display: inline; margin: 0; }
.link-btn {
  background: none; border: none; padding: 0; color: var(--side-muted);
  font-size: 12px; cursor: pointer; font-family: inherit;
}
.link-btn:hover { color: #fff; }

/* ---- 频道设置弹出菜单 ----
   挂在 <body> 上用 fixed 定位。不能挂进 .channel-block：那里是 overflow:auto，
   菜单会被裁掉半截（尤其靠下的频道）。 */
.chan-menu {
  position: fixed; z-index: 80; min-width: 184px; max-width: 250px;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--r-md);
  box-shadow: var(--sh-3); padding: 6px;
}
.chan-menu-title {
  font-size: 12px; font-weight: 700; padding: 4px 8px 8px;
  border-bottom: 1px solid var(--border); margin-bottom: 6px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chan-menu-label { font-size: 11px; color: var(--text-muted); padding: 7px 8px 2px; }
.chan-menu-item {
  display: flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 5px 8px; border-radius: var(--r-sm); font-size: 13px;
}
.chan-menu-item:hover { background: var(--bg-sunken); }
.chan-menu-item input { margin: 0; flex: 0 0 auto; }
.chan-menu-foot {
  border-top: 1px solid var(--border); margin-top: 6px; padding: 7px 8px 2px; font-size: 12px;
}

/* 设置页里的行内勾选 */
.check-inline { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }

/* 主题切换开关：侧栏里一套、登录页浮动一套 */
.theme-toggle {
  width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 1px solid var(--side-line); border-radius: var(--r-sm);
  color: var(--side-muted); font-size: 13px; line-height: 1; font-family: inherit;
  cursor: pointer; transition: color .12s ease, background .12s ease;
}
.theme-toggle:hover { color: #fff; background: var(--side-hover); }

/* 登录/注册页没有侧栏，用中性色的浮动开关 */
.theme-toggle--floating {
  position: fixed; top: 18px; right: 20px; z-index: 20;
  width: 30px; height: 30px; font-size: 14px;
  border-color: var(--border-strong); color: var(--text-muted);
  background: var(--bg); box-shadow: var(--sh-1);
}
.theme-toggle--floating:hover { color: var(--brand-700); background: var(--brand-50); }

/* ==========================================================================
   主区
   ========================================================================== */

.main {
  flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden;
  background: var(--bg); position: relative;   /* 「回到底部」按钮的定位基准 */
}

.channel-header {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 13px 22px; background: var(--bg);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--sh-1); position: relative; z-index: 2;
}
.channel-header::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: linear-gradient(90deg, var(--brand-500), var(--brand-300) 45%, transparent 85%);
  opacity: .5;
}
.channel-title { font-size: 16.5px; font-weight: 700; color: var(--text); }
.channel-title::before {
  content: "#"; color: var(--brand-400); font-weight: 700; margin-right: 3px;
}
.channel-meta { color: var(--text-muted); font-size: 12.5px; }
.spacer { flex: 1; }

#conn-state { font-weight: 600; }

/* ---------------- 消息流 ---------------- */

/* 刻意不用 scroll-behavior: smooth：图片异步加载会把内容撑高，
   平滑滚动会与「保持在底部」的重定位互相打架。 */
.messages { flex: 1; overflow-y: auto; padding: 10px 0 88px; }

.post {
  display: flex; gap: 13px; padding: 9px 22px;
  border-left: 3px solid transparent;
  transition: background .12s ease, border-color .12s ease;
}
.post:hover { background: var(--brand-50); border-left-color: var(--brand-200); }

.avatar {
  width: 38px; height: 38px; flex: 0 0 38px; border-radius: var(--r-full);
  background: linear-gradient(140deg, var(--brand-100), var(--brand-200));
  color: var(--brand-800); font-weight: 700; font-size: 13px; letter-spacing: .02em;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  box-shadow: 0 0 0 1px #0000000a inset;
}
/* 没有头像的发送者用文字缩写。颜色按名字哈希固定，整体仍在红/暖色系内，
   既能区分不同发送者，又不会破坏「红色为主」的统一感。 */
.avatar[data-tone="0"] { background: linear-gradient(140deg,#fff1f1,#ffdcdd); color:#8a1a1f; }
.avatar[data-tone="1"] { background: linear-gradient(140deg,#ffe7e7,#ffc4c6); color:#7d161a; }
.avatar[data-tone="2"] { background: linear-gradient(140deg,#fdeae4,#f8cec3); color:#8a3d1f; }
.avatar[data-tone="3"] { background: linear-gradient(140deg,#f8e8ee,#eec8d5); color:#7d1f3c; }
.avatar[data-tone="4"] { background: linear-gradient(140deg,#f4ebe6,#e6d4c8); color:#7a4a2a; }
.avatar[data-tone="5"] { background: linear-gradient(140deg,#efeae9,#ddd2d0); color:#4c3b39; }
.avatar img { width: 100%; height: 100%; object-fit: cover; }

.post-main { min-width: 0; flex: 1; }
.post-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.post-author { font-weight: 700; color: var(--text); font-size: 14px; }
/* 机器人标签出现在绝大多数消息上，刻意弱化，避免抢走红色重点 */
.bot-tag {
  font-size: 10px; font-weight: 600; letter-spacing: .02em;
  color: var(--text-muted); background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-sm); padding: 0 5px; line-height: 1.6;
}
.post-time { color: var(--text-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.post-edited { color: var(--text-muted); font-size: 11px; font-style: italic; }
.post-body { margin-top: 3px; color: var(--text-soft); overflow-wrap: anywhere; }

/* 消息正文里的 Markdown 元素 */
.post-body p { margin: 0 0 9px; }
.post-body p:last-child { margin-bottom: 0; }
.post-body strong { color: var(--text); font-weight: 700; }
/* 正文里的图片多为外链长图，必须限高，否则一条消息就占满整屏。
   限高后点击可放大查看原图（见 app.js 的 lightbox）。 */
.post-body img {
  max-width: min(100%, 460px); max-height: 420px; width: auto; height: auto;
  object-fit: contain; border-radius: var(--r-md); vertical-align: top;
  border: 1px solid var(--border); box-shadow: var(--sh-1);
  cursor: zoom-in; transition: box-shadow .15s ease;
}
.post-body img:hover { box-shadow: var(--sh-2); }
.post-body h1, .post-body h2, .post-body h3 {
  margin: 14px 0 6px; font-weight: 700; color: var(--text); line-height: 1.4;
}
.post-body h1 { font-size: 18px; }
.post-body h2 { font-size: 16px; }
.post-body h3 { font-size: 14.5px; }
.post-body ul, .post-body ol { margin: 6px 0 9px; padding-left: 22px; }
.post-body li { margin: 3px 0; }
.post-body pre {
  background: var(--bg-sunken); border: 1px solid var(--border);
  border-left: 3px solid var(--brand-300);
  border-radius: var(--r-sm); padding: 11px 13px; margin: 9px 0;
  overflow-x: auto; font-size: 13px; line-height: 1.6;
  font-family: "Cascadia Mono", Consolas, "Courier New", monospace;
}
.post-body code {
  background: var(--bg-sunken); border: 1px solid var(--border);
  padding: 1px 5px; border-radius: var(--r-sm); font-size: 13px;
  font-family: "Cascadia Mono", Consolas, "Courier New", monospace;
}
.post-body pre code { background: none; border: none; padding: 0; font-size: inherit; }
.post-body blockquote {
  margin: 9px 0; padding: 2px 0 2px 13px;
  border-left: 3px solid var(--brand-300); color: var(--text-muted);
}
.post-body a { color: var(--link); text-decoration: underline; text-underline-offset: 2px; }
.post-body a:hover { color: var(--link-hover); }
.post-body table { border-collapse: collapse; margin: 9px 0; font-size: 13px; }
.post-body th, .post-body td { border: 1px solid var(--border); padding: 5px 10px; }
.post-body th { background: var(--bg-soft); font-weight: 600; }
.post-body hr { border: none; border-top: 1px solid var(--border); margin: 14px 0; }

.post.deleted .post-body { color: var(--text-muted); font-style: italic; }
.post.flash { animation: flash 1.8s ease-out; }
@keyframes flash {
  0%   { background: var(--brand-100); border-left-color: var(--brand-500); }
  100% { background: transparent; border-left-color: transparent; }
}

.fav-btn {
  background: none; border: none; cursor: pointer; color: var(--star-empty);
  font-size: 15px; padding: 0 3px; line-height: 1;
  font-family: inherit; transition: color .12s ease, transform .12s ease;
}
.fav-btn:hover { color: var(--brand-400); transform: scale(1.15); }
.fav-btn.is-on { color: var(--brand-500); }

/* ---------------- 附件 ---------------- */

.attachments { margin-top: 9px; display: flex; flex-direction: column; gap: 9px; }
.att-image { max-width: 440px; }
.att-image img {
  max-width: 100%; max-height: 440px; border-radius: var(--r-md);
  border: 1px solid var(--border); box-shadow: var(--sh-2);
  cursor: zoom-in; display: block; transition: transform .15s ease;
}
.att-image img:hover { transform: translateY(-1px); }
.att-video video {
  max-width: 500px; border-radius: var(--r-md);
  border: 1px solid var(--border); box-shadow: var(--sh-2);
}
.att-audio audio {
  width: 300px; max-width: 100%; height: 38px;
  border-radius: var(--r-md); border: 1px solid var(--border);
  background: var(--bg-soft); display: block;
}
.att-file {
  display: inline-flex; align-items: center; gap: 9px; padding: 9px 13px;
  border: 1px solid var(--border); border-radius: var(--r-md); background: var(--bg-soft);
  color: var(--text); max-width: 480px; transition: border-color .12s ease, background .12s ease;
}
.att-file:hover { text-decoration: none; border-color: var(--brand-300); background: var(--brand-50); }
.att-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.att-missing {
  font-size: 12.5px; color: var(--text-muted);
  border: 1px dashed var(--border-strong); border-radius: var(--r-md);
  padding: 8px 12px; display: inline-block; background: var(--bg-soft);
}

.reactions { margin-top: 7px; display: flex; gap: 6px; flex-wrap: wrap; }
.reaction {
  font-size: 12px; background: var(--brand-50); border: 1px solid var(--brand-200);
  border-radius: var(--r-full); padding: 2px 9px; color: var(--brand-800);
}

/* ---------------- 回到底部 ---------------- */

/* 向上翻历史、或新消息到达时，用一个浮动按钮回到最新，比手动滚到底友好得多。 */
.jump-bottom {
  position: absolute; right: 26px; bottom: 22px; z-index: 5;
  display: none; align-items: center; gap: 6px;
  padding: 8px 15px; border-radius: var(--r-full);
  border: 1px solid var(--brand-300);
  background: var(--bg); color: var(--brand-800);
  font-size: 12.5px; font-weight: 600; font-family: inherit;
  cursor: pointer; box-shadow: var(--sh-2);
}
.jump-bottom::after { content: "↓"; font-size: 13px; }
.jump-bottom:hover { background: var(--brand-50); border-color: var(--brand-400); }
.jump-bottom.is-visible { display: inline-flex; }
.jump-bottom.has-new {
  background: linear-gradient(180deg, var(--brand-600), var(--brand-700));
  color: #fff; border-color: transparent; box-shadow: var(--sh-brand);
}
.jump-bottom.has-new:hover { filter: brightness(1.06); background: linear-gradient(180deg, var(--brand-600), var(--brand-700)); }

/* ---------------- 图片放大 ---------------- */

.lightbox {
  position: fixed; inset: 0; background: #1a0d0fe6; backdrop-filter: blur(3px);
  display: none; align-items: center; justify-content: center; z-index: 100; padding: 24px;
  overflow: auto;
}
.lightbox.is-open { display: flex; }
/* 切到原始尺寸后，长截图会超出视口：改为顶部对齐并允许滚动阅读 */
.lightbox.is-actual { align-items: flex-start; }
/* 原始尺寸模式必须解除 max-width/max-height，否则长截图仍会被压回容器高度、
   用户看到的就是「点了没变化」。解除后由容器 overflow:auto 提供滚动阅读。 */
.lightbox img.is-actual { max-width: none; max-height: none; margin: auto; cursor: zoom-out; }
.lightbox img { cursor: zoom-in; }
/* 实际显示尺寸由 app.js 按原图比例算好（小图最多放大 3 倍），
   这里的 max-* 只是兜底，防止极端尺寸溢出。 */
.lightbox img { max-width: 100%; max-height: 100%; border-radius: var(--r-md); box-shadow: var(--sh-3); }
.lightbox .close {
  position: absolute; top: 18px; right: 26px; color: #fff; font-size: 30px; line-height: 1;
  cursor: pointer; background: none; border: none; font-family: inherit; opacity: .85;
}
.lightbox .close:hover { opacity: 1; }

/* ---------------- 提示条 ---------------- */

.banner {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 22px; font-size: 13px; border-bottom: 1px solid transparent;
}
.banner::before { font-size: 14px; }
/* 提示条目前只有两种用途：会员临期提醒与已到期提醒 */
.banner-warn {
  background: var(--warn-bg); color: var(--warn); border-bottom-color: var(--warn-border);
}
.banner-warn::before { content: "⚠"; }
.banner-error {
  background: var(--brand-100); color: var(--brand-800); border-bottom-color: var(--brand-300);
}
.banner-error::before { content: "!"; font-weight: 800; }
.banner strong { font-weight: 700; }
.banner-body { opacity: .85; }

/* ---------------- 加载骨架屏 ----------------

   服务端已把外壳渲染出来，但消息由 JS 构建。这段骨架就补在
   「HTML 已绘制、消息还没画出来」之间，避免一片空白。 */

.skeleton { padding: 8px 22px; }
.skeleton-row { display: flex; gap: 13px; padding: 9px 0; }
.sk-avatar {
  width: 38px; height: 38px; flex: 0 0 38px; border-radius: var(--r-full);
  background: var(--bg-sunken);
}
.sk-lines { flex: 1; min-width: 0; padding-top: 4px; }
.sk-line {
  height: 11px; border-radius: var(--r-full); margin-bottom: 9px;
  background: var(--bg-sunken);
}
.sk-line.w-30 { width: 30%; }
.sk-line.w-88 { width: 88%; }
.sk-line.w-72 { width: 72%; }
.sk-line.w-54 { width: 54%; }
.skeleton .sk-avatar,
.skeleton .sk-line {
  background-image: linear-gradient(90deg, var(--bg-sunken) 0%, var(--bg-soft) 50%, var(--bg-sunken) 100%);
  background-size: 200% 100%;
  animation: cf-shimmer 1.4s ease-in-out infinite;
}
@keyframes cf-shimmer {
  0%   { background-position: 140% 0; }
  100% { background-position: -40% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .skeleton .sk-avatar, .skeleton .sk-line { animation: none; }
}

/* ---------------- 超长消息折叠 ----------------

   一条消息过长时会占满整屏，把其它内容挤下去。 */
.post-body { position: relative; }
.post-body.is-collapsed {
  max-height: min(420px, 58vh);   /* 约视口六成，留出上下文 */
  overflow: hidden;
}
.post-body.is-collapsed::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0; height: 76px;
  background: linear-gradient(180deg, transparent, var(--bg));
  pointer-events: none;
}
.post:hover .post-body.is-collapsed::after {
  background: linear-gradient(180deg, transparent, var(--brand-50));
}
.post-expand {
  margin-top: 6px; padding: 4px 12px;
  background: var(--bg-soft); border: 1px solid var(--border);
  border-radius: var(--r-full);
  color: var(--brand-800); font-size: 12.5px; font-weight: 600; font-family: inherit;
  cursor: pointer;
}
.post-expand:hover { background: var(--brand-50); border-color: var(--brand-300); }

/* ---------------- 相对时间 ---------------- */

.post-time { font-variant-numeric: tabular-nums; }
.post-time.is-recent { color: var(--brand-700); font-weight: 600; }

/* ---------------- 日期分隔与加载 ---------------- */

.day-sep {
  display: flex; align-items: center; gap: 14px; margin: 18px 22px 10px;
  color: var(--text-muted); font-size: 12px; font-weight: 600;
}
.day-sep::before, .day-sep::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.day-sep::before { max-width: 40px; }

.load-more { text-align: center; padding: 14px; }

.empty-state { margin: auto; text-align: center; color: var(--text-muted); padding: 70px 20px; }
.empty-state h2 { color: var(--text); font-size: 19px; margin: 0 0 8px; }
.empty-state::before {
  content: "◍"; display: block; font-size: 40px; color: var(--brand-200);
  margin-bottom: 12px; line-height: 1;
}

/* ==========================================================================
   表单与按钮
   ========================================================================== */

/* 登录 / 注册页：淡红渐变背景 + 居中白卡 */
.auth-wrap {
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 40px 20px; overflow-y: auto;
  background:
    radial-gradient(900px 420px at 50% -8%, var(--brand-100) 0%, transparent 70%),
    linear-gradient(180deg, var(--brand-50) 0%, var(--bg) 55%);
}
.auth-card {
  width: 100%; max-width: 400px; background: var(--bg);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: var(--sh-3); padding: 32px 32px 28px;
}
.auth-brand {
  display: flex; align-items: center; gap: 10px; margin-bottom: 22px;
  padding-bottom: 18px; border-bottom: 1px solid var(--border);
}
.auth-brand .brand-mark { width: 32px; height: 32px; flex: 0 0 32px; font-size: 15px; }
.auth-brand-name { font-weight: 800; font-size: 16px; letter-spacing: -.01em; }

.form-narrow { max-width: 400px; margin: 60px auto; padding: 0 20px; }
.form-title { font-size: 23px; font-weight: 800; margin: 0 0 6px; letter-spacing: -.02em; }
.form-sub { color: var(--text-muted); margin: 0 0 24px; font-size: 13px; }

.field { margin-bottom: 15px; }
.field label {
  display: block; font-size: 12px; font-weight: 600; margin-bottom: 6px;
  color: var(--text-soft); letter-spacing: .01em;
}
.field input[type=text], .field input[type=password], .field input[type=date],
.field input[type=number], .field select, .field textarea {
  width: 100%; padding: 10px 12px; border: 1px solid var(--border-strong);
  border-radius: var(--r-sm); font-size: 14px; font-family: inherit;
  background: var(--bg); color: var(--text); transition: border-color .12s ease, box-shadow .12s ease;
}
.field textarea { min-height: 96px; resize: vertical; line-height: 1.6; }
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--border-hover); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--brand-500);
  box-shadow: 0 0 0 3px var(--brand-100);
}
.field input::placeholder, .field textarea::placeholder { color: var(--placeholder); }

.checkbox-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 7px; }
.checkbox-grid label {
  display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 400;
  color: var(--text-soft); padding: 5px 8px; border-radius: var(--r-sm);
  transition: background .12s ease;
}
.checkbox-grid label:hover { background: var(--brand-50); }
.checkbox-grid input[type=checkbox] { accent-color: var(--brand-500); width: 15px; height: 15px; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 10px 18px; border-radius: var(--r-sm); border: 1px solid transparent;
  /* 用 600->700 而非 500->600：白字对比度从 3.9:1 提到 4.8~6.7:1，达到 AA */
  background: linear-gradient(180deg, var(--brand-600), var(--brand-700));
  color: #fff; font-size: 14px; font-weight: 600; font-family: inherit;
  cursor: pointer; box-shadow: var(--sh-brand);
  transition: filter .12s ease, transform .06s ease, box-shadow .12s ease;
}
.btn:hover { filter: brightness(1.06); text-decoration: none; color: #fff; }
.btn:active { transform: translateY(1px); box-shadow: none; }
.btn:disabled { opacity: .55; cursor: not-allowed; box-shadow: none; }
.btn-block { width: 100%; }
.btn-secondary {
  background: var(--bg); color: var(--text-soft); border-color: var(--border-strong); box-shadow: var(--sh-1);
}
.btn-secondary:hover { background: var(--brand-50); border-color: var(--brand-300); color: var(--brand-800); filter: none; }
.btn-small { padding: 5px 11px; font-size: 12.5px; }
.btn-danger { background: linear-gradient(180deg, #a01e23, #7d161a); box-shadow: none; }
.btn-danger:hover { filter: brightness(1.12); }

.msg-error, .msg-ok {
  display: flex; align-items: flex-start; gap: 8px;
  border-radius: var(--r-sm); padding: 10px 13px; margin-bottom: 16px; font-size: 13px;
}
.msg-error { background: var(--brand-100); color: var(--brand-800); border: 1px solid var(--brand-300); }
.msg-error::before { content: "✕"; font-weight: 700; }
.msg-note {
  background: var(--bg-soft); border: 1px solid var(--border);
  border-radius: var(--r-sm); padding: 10px 13px; margin-bottom: 16px;
  font-size: 12.5px; line-height: 1.7; color: var(--text-muted);
}
.msg-note strong { color: var(--brand-700); }
.msg-ok { background: var(--ok-bg); color: #14532d; border: 1px solid var(--ok-border); }
.msg-ok::before { content: "✓"; font-weight: 700; }

/* ==========================================================================
   管理后台
   ========================================================================== */

.admin-nav {
  display: flex; gap: 5px; flex-wrap: wrap; padding: 10px 22px;
  border-bottom: 1px solid var(--border); background: var(--bg-soft);
}
.admin-nav a {
  padding: 6px 13px; border-radius: var(--r-full); font-size: 13px; font-weight: 500;
  color: var(--text-soft); border: 1px solid transparent;
  transition: background .12s ease, color .12s ease;
}
.admin-nav a:hover { background: var(--bg); border-color: var(--border); text-decoration: none; }
.admin-nav a.is-active {
  background: linear-gradient(180deg, var(--brand-500), var(--brand-600));
  color: #fff; box-shadow: var(--sh-brand);
}

.admin-body { flex: 1; overflow-y: auto; padding: 24px 22px 48px; }
.admin-body h1 { font-size: 20px; margin: 0 0 6px; font-weight: 800; letter-spacing: -.02em; }
.admin-body h2 {
  font-size: 15px; margin: 28px 0 12px; font-weight: 700;
  display: flex; align-items: center; gap: 8px;
}
.admin-body h2::before {
  content: ""; width: 3px; height: 15px; border-radius: 2px;
  background: var(--brand-500); flex: 0 0 3px;
}
.admin-body h2:first-child { margin-top: 0; }

.cards {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(158px, 1fr));
  gap: 13px; margin: 14px 0 6px;
}
.card {
  position: relative; overflow: hidden;
  border: 1px solid var(--border); border-radius: var(--r-md); padding: 14px 16px;
  background: linear-gradient(180deg, var(--bg), var(--brand-50));
  box-shadow: var(--sh-1);
}
.card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: linear-gradient(90deg, var(--brand-500), var(--brand-300));
}
.card .k { font-size: 12px; color: var(--text-muted); font-weight: 500; }
.card .v {
  font-size: 24px; font-weight: 800; margin-top: 3px; color: var(--brand-700);
  letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}

table.grid {
  width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px;
  border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden;
  background: var(--bg); box-shadow: var(--sh-1);
}
table.grid th, table.grid td {
  border-bottom: 1px solid var(--border); padding: 10px 12px;
  text-align: left; vertical-align: top;
}
table.grid th {
  background: var(--bg-soft); font-size: 12px; font-weight: 700;
  color: var(--text-soft); white-space: nowrap; letter-spacing: .02em;
}
table.grid tbody tr:last-child td { border-bottom: none; }
table.grid tbody tr:hover td { background: var(--brand-50); }

.tag {
  display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: .02em;
  padding: 2px 8px; border-radius: var(--r-full); border: 1px solid transparent;
  line-height: 1.6; vertical-align: middle;
}
.tag-pending { background: var(--warn-bg); color: var(--warn); border-color: var(--warn-border); }
.tag-active  { background: var(--ok-bg); color: #14532d; border-color: var(--ok-border); }
.tag-rejected{ background: var(--bg-sunken); color: var(--text-muted); border-color: var(--border); }
.tag-disabled{ background: var(--brand-100); color: var(--brand-800); border-color: var(--brand-300); }
.tag-expired { background: var(--brand-600); color: #fff; }
.tag-ok      { background: var(--ok-bg); color: #14532d; border-color: var(--ok-border); }
.tag-bad     { background: var(--brand-100); color: var(--brand-800); border-color: var(--brand-300); }
.tag-action  { background: var(--bg-sunken); color: var(--text); border-color: var(--border-strong); }

.inline-form { display: inline-flex; gap: 5px; align-items: center; flex-wrap: wrap; }
.inline-form input[type=text], .inline-form input[type=date], .inline-form input[type=number],
.inline-form select {
  padding: 5px 9px; border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  font-size: 12.5px; font-family: inherit; background: var(--bg); color: var(--text);
}
.inline-form input:focus, .inline-form select:focus {
  outline: none; border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-100);
}
.inline-form input[type=text].narrow { width: 120px; }

.details { margin: 4px 0; }
.details summary {
  cursor: pointer; color: var(--brand-700); font-size: 12.5px; font-weight: 600;
  list-style: none; display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 0; user-select: none;
}
.details summary::-webkit-details-marker { display: none; }
.details summary::before { content: "▸"; transition: transform .15s ease; display: inline-block; }
.details[open] > summary::before { transform: rotate(90deg); }
.details[open] > summary { margin-bottom: 10px; }
.details > form, .details > div { padding-left: 14px; border-left: 2px solid var(--brand-200); }

/* 会员详情页：两列面板布局，窄屏自动堆叠 */
.detail-grid {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
  align-items: start;
}
.panel {
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--bg); box-shadow: var(--sh-1); padding: 16px 18px;
}
.panel-wide { grid-column: 1 / -1; }
.panel h2 {
  font-size: 14px; font-weight: 700; margin: 0 0 12px;
  display: flex; align-items: center; gap: 8px;
}
.panel h2::before {
  content: ""; width: 3px; height: 14px; border-radius: 2px;
  background: var(--brand-500); flex: 0 0 3px;
}
.panel .field:last-of-type { margin-bottom: 12px; }
.panel table.grid { box-shadow: none; }

/* ==========================================================================
   工具类
   ========================================================================== */

.muted { color: var(--text-muted); }
.small { font-size: 12px; }
.pad { padding: 10px; }
.mono {
  font-family: "Cascadia Mono", Consolas, "Courier New", monospace;
  font-size: 12px; color: var(--text-soft);
}

/* ==========================================================================
   窄屏
   ========================================================================== */

@media (max-width: 860px) {
  .layout { flex-direction: column; }
  .sidebar {
    width: 100%; flex: 0 0 auto; max-height: 44vh;
    border-right: none; border-bottom: 1px solid #00000040;
  }
  .channel-block { max-height: 24vh; }
  .main { flex: 1; min-height: 0; }
  .post { padding: 9px 14px; gap: 10px; }
  .channel-header, .banner, .admin-nav, .admin-body { padding-left: 14px; padding-right: 14px; }
  .att-image, .att-image img, .att-video video { max-width: 100%; }
  .avatar { width: 34px; height: 34px; flex: 0 0 34px; }
  .cards { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); }
}

/* 触屏没有 hover：把「⋮」入口常亮，否则永远点不出来 */
@media (hover: none) {
  .chan-more { opacity: 1; }
}

/* 打印时去掉交互装饰（留个口子，方便以后做导出） */
@media print {
  .sidebar, .admin-nav, .fav-btn, .load-more { display: none !important; }
  .post:hover { background: none; border-left-color: transparent; }
}


/* ==========================================================================
   深色主题

   data-theme 由 <head> 内联脚本在首屏渲染前设置（避免闪白），
   用户选择存 localStorage；没有选择时跟随系统。
   ========================================================================== */

:root[data-theme="dark"] {
  color-scheme: dark;   /* 让原生滚动条与表单控件跟着变深 */

  /* 品牌红在深色底上要提亮，否则发闷。
     同时把「深红=文字色」的角色反转（浅色下 brand-800 是深字，深色下要变浅字）。 */
  --brand-50:  #2b1418;
  --brand-100: #3b1a1f;
  --brand-200: #56242b;
  --brand-300: #7e3038;
  --brand-400: #c2484e;
  --brand-500: #ef5a60;
  --brand-600: #e5484d;
  --brand-700: #cf3d42;
  --brand-800: #ffb4b7;
  --brand-900: #ffd7d9;
  --brand-950: #ffecec;

  --side-top:    #1b0e11;
  --side-bottom: #140a0c;
  --side-text:   #e9dadc;
  --side-muted:  #a2898c;
  --side-hover:  #ffffff12;
  --side-line:   #ffffff14;

  --bg:            #171314;
  --bg-soft:       #1e191a;
  --bg-sunken:     #251f20;
  --border:        #302829;
  --border-strong: #3f3637;
  --border-hover:  #4a4142;
  --placeholder:   #756a6c;
  --text:          #f3edee;
  --text-soft:     #d5cacb;
  --text-muted:    #9e9193;

  --link:        #ff9a9e;
  --link-hover:  #ffc0c2;
  --star-empty:  #6b5f61;
  --scroll-thumb: #3b3335;
  --scroll-thumb-hover: #4d4345;

  --ok:         #4ec97a;
  --ok-text:    #6fe09b;
  --ok-bg:      #15301f;
  --ok-border:  #23512f;
  --warn:       #e6bb52;
  --warn-bg:    #322a13;
  --warn-border: #4e421d;

  /* 深色下阴影几乎不可见，层次主要靠边框；阴影只保留极轻的一层 */
  --sh-1: 0 1px 2px #00000040;
  --sh-2: 0 2px 10px #00000055;
  --sh-3: 0 10px 34px #00000070;
  --sh-brand: 0 2px 10px #e5484d38;
}

/* 无头像发送者的文字缩写：深色下换成深底浅字，仍只走红/暖色家族 */
:root[data-theme="dark"] .avatar[data-tone="0"] { background: linear-gradient(140deg,#3c1b1f,#4f2228); color:#ffcdd0; }
:root[data-theme="dark"] .avatar[data-tone="1"] { background: linear-gradient(140deg,#472026,#5d2a31); color:#ffd2d4; }
:root[data-theme="dark"] .avatar[data-tone="2"] { background: linear-gradient(140deg,#412a20,#55382a); color:#ffdcc4; }
:root[data-theme="dark"] .avatar[data-tone="3"] { background: linear-gradient(140deg,#3f2130,#552b3f); color:#ffd0e0; }
:root[data-theme="dark"] .avatar[data-tone="4"] { background: linear-gradient(140deg,#3a302a,#4d4038); color:#f0dcc8; }
:root[data-theme="dark"] .avatar[data-tone="5"] { background: linear-gradient(140deg,#332c2b,#453c3a); color:#ddd0cd; }

/* 深色下正文图片的浅色边框会显得突兀 */
:root[data-theme="dark"] .post-body img,
:root[data-theme="dark"] .att-image img { border-color: var(--border-strong); }
/* 「响提示音勾了、声音总开关没开」的行内提醒（设置页） */
.warn-inline {
  /* 注意：不能直接写 display:inline-block——作者样式会盖掉 [hidden] 的 display:none，
     结果「隐藏」的提醒一直挂在页面上。所以默认 none，只有没 hidden 时才显示。 */
  display: none; margin-left: 10px; padding: 2px 8px; border-radius: var(--r-sm);
  background: var(--brand-100); color: var(--brand-800); border: 1px solid var(--brand-300);
  font-size: 12px;
}
.warn-inline:not([hidden]) { display: inline-block; }
/* 设置页「会不会提示」列：会提示标绿，一眼看出哪几个频道是哑的 */
.ok-inline { color: var(--ok); font-weight: 600; }
