/* ============================================================
   学习书架 · 公共样式（设计令牌 + 通用组件）
   ------------------------------------------------------------
   全部页面共用。类名统一 .bs- 前缀，避免和既有 18 个页面的
   样式互相污染。

   设计约束（用户明确要求，别改）：
     · 纸感浅色：#f4f3ef 背景，纯白卡片，边框 #e6e4df
     · 只用站点四色：墨黑 #1b1f24 / 蓝 #0f5cad / 绿 #0e7a5f / 紫 #5b43c6 / 金 #8a5a08
     · 字重只用 400 / 600 / 700
     · 正文 15px，小字 12.5px
     · 图标一律线性 SVG，不用 emoji
     · 每本书都要有封面（左侧书脊 + 右侧书页切口 + 分类色渐变）
   ============================================================ */

:root{
  --bs-ink:#1b1f24;
  --bs-ink2:#3a4046;
  --bs-muted:#6b7280;
  --bs-faint:#8a8780;
  --bs-bg:#f4f3ef;
  --bs-card:#fff;
  --bs-line:#e6e4df;
  --bs-line2:#f1efe9;

  --bs-blue:#0f5cad;   --bs-blue-d:#0b4185;
  --bs-teal:#0e7a5f;   --bs-teal-d:#0a5a45;
  --bs-purple:#5b43c6; --bs-purple-d:#4b34a8;
  --bs-amber:#8a5a08;  --bs-amber-d:#6d4706;
  --bs-red:#b4232a;

  --bs-g-design:linear-gradient(155deg,#6b52d6 0%,#4b34a8 100%);
  --bs-g-aesthetic:linear-gradient(155deg,#a9741a 0%,#7a4f06 100%);
  --bs-g-coding:linear-gradient(155deg,#1a6fc4 0%,#0b4185 100%);
  --bs-g-gamedev:linear-gradient(155deg,#128a6a 0%,#0a5a45 100%);

  --bs-sd:0 1px 2px rgba(27,31,36,.05), 0 10px 26px -14px rgba(27,31,36,.14);
  --bs-sd-lift:0 2px 4px rgba(27,31,36,.06), 0 18px 34px -16px rgba(27,31,36,.22);
}

.bs-num{font-variant-numeric:tabular-nums;}

/* ============================================================
   顶栏
   ============================================================ */
.bs-nav{
  background:var(--bs-card); border-bottom:1px solid var(--bs-line);
  position:sticky; top:0; z-index:60;
}
.bs-nav .in{
  max-width:1180px; margin:0 auto; padding:11px 20px;
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
}
.bs-brand{
  display:flex; align-items:center; gap:9px;
  font-size:15px; font-weight:700; letter-spacing:-.01em;
  color:var(--bs-ink); text-decoration:none; flex:none;
}
.bs-brand .mark{display:flex; gap:2px; align-items:flex-end; height:18px;}
.bs-brand .mark i{width:3.5px; border-radius:1.5px; display:block;}
.bs-brand .mark i:nth-child(1){height:12px; background:var(--bs-purple);}
.bs-brand .mark i:nth-child(2){height:18px; background:var(--bs-blue);}
.bs-brand .mark i:nth-child(3){height:14px; background:var(--bs-teal);}
.bs-brand .mark i:nth-child(4){height:16px; background:var(--bs-amber);}

.bs-search{flex:1; min-width:180px; position:relative;}
.bs-search input{
  width:100%; border:1px solid var(--bs-line); background:#faf9f6;
  border-radius:10px; padding:9px 14px 9px 36px;
  font-size:13.5px; font-family:inherit; color:var(--bs-ink); transition:.16s;
}
.bs-search input:focus{
  outline:none; background:var(--bs-card); border-color:var(--bs-teal);
  box-shadow:0 0 0 3px rgba(14,122,95,.09);
}
.bs-search input::placeholder{color:#b8b5ae;}
.bs-search svg{position:absolute; left:12px; top:50%; transform:translateY(-50%); color:#a8a49c;}

.bs-navlinks{display:flex; gap:3px; flex:none;}
.bs-navlinks a{
  font-size:13px; font-weight:600; color:var(--bs-muted); text-decoration:none;
  padding:7px 13px; border-radius:9px; transition:.16s; white-space:nowrap;
}
.bs-navlinks a:hover{color:var(--bs-ink); background:#f6f5f1;}
.bs-navlinks a.on{color:var(--bs-ink); background:#f1efe9;}

.bs-hdright{display:flex; align-items:center; gap:10px; margin-left:auto; flex:none;}

/* 金币胶囊 */
.bs-wallet{
  display:inline-flex; align-items:center; gap:6px;
  background:#fbf3e2; border:1px solid #efdcb8; border-radius:999px;
  padding:5px 13px; font-size:13px; font-weight:600; color:var(--bs-amber);
}
.bs-wallet .n{font-variant-numeric:tabular-nums;}

/* 金币图标（CSS 画，不用 emoji） */
.bs-coin{
  display:inline-block; width:13px; height:13px; border-radius:50%; flex:none;
  background:radial-gradient(circle at 34% 28%,#efd08a,#a9741a 78%);
  box-shadow:inset 0 0 0 1.4px rgba(255,255,255,.55), 0 1px 2px rgba(109,71,6,.3);
  vertical-align:-2px;
}

/* 头像 */
.bs-ava{
  width:34px; height:34px; border-radius:50%; flex:none; cursor:pointer;
  background:var(--bs-teal); color:#fff;
  display:flex; align-items:center; justify-content:center;
  font-size:13px; font-weight:600; overflow:hidden;
  box-shadow:0 0 0 2px var(--bs-card), 0 0 0 3.5px #d9d6cf;
  border:none; font-family:inherit; padding:0;
}
.bs-ava img{width:100%; height:100%; object-fit:cover;}
.bs-ava.gold{box-shadow:0 0 0 2.5px var(--bs-card), 0 0 0 4.5px #e8d5a8;}

/* ============================================================
   通用组件
   ============================================================ */
.bs-btn{
  display:inline-flex; align-items:center; justify-content:center; gap:7px;
  border:none; border-radius:10px; font-family:inherit;
  font-size:13.5px; font-weight:600; cursor:pointer;
  padding:10px 18px; transition:.16s; white-space:nowrap; text-decoration:none;
}
.bs-btn.solid{background:var(--bs-teal); color:#fff;}
.bs-btn.solid:hover{background:#0c6b53;}
.bs-btn.ink{background:var(--bs-ink); color:#fff;}
.bs-btn.ink:hover{background:#000;}
.bs-btn.line{background:var(--bs-card); border:1px solid var(--bs-line); color:var(--bs-ink2);}
.bs-btn.line:hover{border-color:#cfccc4; color:var(--bs-ink);}
.bs-btn.gold{background:#fbf3e2; color:var(--bs-amber); border:1px solid #efdcb8;}
.bs-btn.gold:hover{background:#f7ead1;}
.bs-btn.sm{padding:6px 12px; font-size:12.5px; border-radius:8px;}
.bs-btn.block{width:100%;}
.bs-btn[disabled]{opacity:.45; cursor:not-allowed;}

.bs-chip{
  display:inline-flex; align-items:center; gap:6px;
  border:1px solid var(--bs-line); background:var(--bs-card);
  color:var(--bs-muted); border-radius:999px; padding:6px 14px;
  font-size:12.5px; font-weight:600; cursor:pointer;
  font-family:inherit; transition:.16s;
}
.bs-chip:hover{color:var(--bs-ink); border-color:#d5d2ca;}
.bs-chip.on{background:var(--bs-ink); border-color:var(--bs-ink); color:#fff;}
.bs-chip .n{font-size:11.5px; opacity:.6;}

.bs-tag{
  display:inline-flex; align-items:center; gap:4px;
  font-size:11px; font-weight:600; border-radius:6px; padding:2px 7px;
}
.bs-tag.live{background:#e3f4ee; color:#0a5a45;}
.bs-tag.voting{background:#fbf3e2; color:var(--bs-amber);}
.bs-tag.reached{background:#efeafd; color:var(--bs-purple);}
.bs-tag.making{background:#eaf2fb; color:var(--bs-blue);}
.bs-tag.ai{background:#f1efe9; color:var(--bs-faint);}

/* ============================================================
   书封面 —— 全站最核心的视觉
   ------------------------------------------------------------
   两种形态，一眼可辨：
     已上架  · 实色渐变 + 书脊高光 + 对角光泽，像一本真书摆在架上
     未上架  · 纸白线稿 + 虚线框 + 分类色描边，像还没印出来的样张
   这个区分是刻意的：用户扫一眼就知道哪些能读、哪些还在做。
   ============================================================ */
.bs-cv{
  position:relative; aspect-ratio:3/4.2; border-radius:2px 8px 8px 2px;
  padding:19px 15px 14px 23px;
  display:flex; flex-direction:column;
  color:#fff; overflow:hidden; flex:none; box-sizing:border-box;
  background:linear-gradient(155deg,var(--c1) 0%,var(--c2) 100%);
  box-shadow:
    0 1px 1px rgba(27,31,36,.10),
    0 16px 28px -18px rgba(27,31,36,.6);
}

/* 四类主色：
   --c1  亮端      --c2  暗端
   --cline 未上架的虚线描边   --cink 未上架的书名色
   --cbg   未上架的淡色底（给线稿卡一层分类色的暗示） */
.bs-cv.design   {--c1:#7a5fe0; --c2:#412c93; --cline:rgba(107,82,214,.55); --cink:#3d2a86; --cbg:#ddd4f9;}
.bs-cv.aesthetic{--c1:#b5811f; --c2:#6d4405; --cline:rgba(169,116,26,.58); --cink:#6d4405; --cbg:#f2e0bc;}
.bs-cv.coding   {--c1:#2280d4; --c2:#083776; --cline:rgba(26,111,196,.55); --cink:#083776; --cbg:#d3e5f8;}
.bs-cv.gamedev  {--c1:#159a76; --c2:#08503e; --cline:rgba(18,138,106,.55); --cink:#08503e; --cbg:#ceebe3;}

/* 书脊 */
.bs-cv .spine{
  position:absolute; left:0; top:0; bottom:0; width:11px;
  background:linear-gradient(90deg,rgba(0,0,0,.42) 0%,rgba(0,0,0,.22) 42%,rgba(0,0,0,.04) 100%);
}
/* 圆背内侧的一条高光，给书脊体积感 */
.bs-cv .spine::after{
  content:''; position:absolute; right:1px; top:0; bottom:0; width:1px;
  background:rgba(255,255,255,.24);
}
/* 对角光泽：左上角一团柔光 + 一道斜向反光 */
.bs-cv .gloss{
  position:absolute; inset:0; pointer-events:none;
  background:
    radial-gradient(120% 78% at 8% 0%, rgba(255,255,255,.20) 0%, rgba(255,255,255,0) 56%),
    linear-gradient(118deg, rgba(255,255,255,.11) 0%, rgba(255,255,255,0) 38%,
                            rgba(255,255,255,0) 62%, rgba(255,255,255,.06) 100%);
}
/* 书页切口 */
.bs-cv .pages{
  position:absolute; right:0; top:3px; bottom:3px; width:3px;
  border-radius:0 3px 3px 0;
  background:repeating-linear-gradient(180deg,#fff 0 1.5px,rgba(0,0,0,.08) 1.5px 3px);
}
/* 布面压纹，只在上半部分可见，越往下越淡 */
.bs-cv .grain{
  position:absolute; inset:0; pointer-events:none; opacity:.55;
  background:repeating-linear-gradient(0deg,rgba(255,255,255,.055) 0 1px,rgba(255,255,255,0) 1px 3px);
  -webkit-mask-image:linear-gradient(180deg,#000 0%,rgba(0,0,0,0) 64%);
  mask-image:linear-gradient(180deg,#000 0%,rgba(0,0,0,0) 64%);
}

.bs-cv .ct{
  position:relative; font-size:15px; font-weight:600; line-height:1.38;
  letter-spacing:.012em; text-shadow:0 1px 4px rgba(0,0,0,.3);
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden;
}
/* 书名下压一条短线做装饰 */
.bs-cv .ct::after{
  content:''; display:block; width:20px; height:2px; margin-top:9px;
  background:rgba(255,255,255,.55); border-radius:1px;
}
.bs-cv .cs{
  position:relative; font-size:10.5px; margin-top:9px; line-height:1.55;
  color:rgba(255,255,255,.76);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.bs-cv .cf{
  position:relative; margin-top:auto; padding-top:12px; font-size:10.5px;
  display:flex; align-items:center; gap:8px;
}
.bs-cv .cf > span:first-child{color:rgba(255,255,255,.68);}
.bs-cv .badge{
  margin-left:auto; flex:none; font-size:10px; font-weight:600;
  border-radius:5px; padding:2px 7px; background:rgba(255,255,255,.92);
  box-shadow:0 1px 2px rgba(0,0,0,.1);
}
.bs-cv .badge.live{color:#0a5a45;}

/* ---------------- 未上架：样张形态 ----------------
   目标是在 3D 视角下也看得见 —— 纯白卡片斜着看会变成一片空白，
   所以给它一层分类色的淡底，再叠一道「图纸」斜纹。 */
.bs-cv.pending{
  background:var(--cbg);
  border:1.5px dashed var(--cline);
  color:var(--cink);
  box-shadow:0 1px 2px rgba(27,31,36,.06);
}
.bs-cv.pending .spine{
  width:8px; border-radius:1px 0 0 1px;
  background:var(--c1); opacity:.72;
}
.bs-cv.pending .spine::after{display:none;}
.bs-cv.pending .gloss{
  background:radial-gradient(110% 68% at 10% 0%, rgba(255,255,255,.92) 0%, rgba(255,255,255,0) 62%);
}
/* 斜纹：一眼看出「还没印出来」 */
.bs-cv.pending .grain{
  display:block; opacity:.55;
  background:repeating-linear-gradient(45deg, var(--cline) 0 1px, rgba(255,255,255,0) 1px 7px);
  -webkit-mask-image:linear-gradient(180deg, rgba(0,0,0,.55) 0%, rgba(0,0,0,0) 72%);
  mask-image:linear-gradient(180deg, rgba(0,0,0,.55) 0%, rgba(0,0,0,0) 72%);
}
.bs-cv.pending .pages{
  background:repeating-linear-gradient(180deg,#fff 0 1.5px,var(--cline) 1.5px 3px);
}
.bs-cv.pending .ct{color:var(--cink); text-shadow:none; font-size:14.5px;}
.bs-cv.pending .ct::after{background:var(--c1); opacity:.6;}
.bs-cv.pending .cs{color:#7c7a74;}
.bs-cv.pending .cf > span:first-child{color:#7c7a74;}
.bs-cv.pending .badge{background:var(--c1); color:#fff; box-shadow:0 1px 2px rgba(0,0,0,.14);}

/* 已加入书架时封面左下角的小标记 */
.bs-cv .inshelf{
  position:absolute; left:14px; bottom:14px;
  width:18px; height:18px; border-radius:5px;
  background:rgba(255,255,255,.95);
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 1px 3px rgba(0,0,0,.18);
}
.bs-cv .inshelf svg{color:var(--bs-teal);}
.bs-cv.pending .inshelf{background:var(--c1);}
.bs-cv.pending .inshelf svg{color:#fff;}

/* ============================================================
   书卡片（网格单元）
   桌面一行 4 本 —— 刻意留白，不要把书架塞满
   ============================================================ */
.bs-grid{
  display:grid; gap:26px 22px;
  grid-template-columns:repeat(auto-fill,minmax(228px,1fr));
}
.bs-bk{display:flex; flex-direction:column; min-width:0;}
.bs-bk .cover-wrap{position:relative; cursor:pointer;}
.bs-bk .cover-wrap .bs-cv{transition:transform .18s, box-shadow .18s;}
.bs-bk:hover .bs-cv{
  transform:translateY(-3px);
  box-shadow:0 2px 3px rgba(27,31,36,.1), 0 20px 30px -18px rgba(27,31,36,.6);
}
.bs-bk .meta{padding:10px 2px 0;}
.bs-bk .meta b{
  display:block; font-size:13.5px; font-weight:600; line-height:1.45;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.bs-bk .meta small{display:block; font-size:11.5px; color:var(--bs-muted); margin-top:2px;}

.bs-prog{margin-top:9px;}
.bs-prog .row{
  display:flex; align-items:baseline; gap:6px;
  font-size:11px; color:var(--bs-muted); margin-bottom:5px;
}
.bs-prog .row b{margin-left:auto; color:var(--bs-amber); font-weight:600; font-size:11px;}
.bs-track{height:5px; border-radius:999px; background:var(--bs-line2); overflow:hidden;}
.bs-track > i{display:block; height:100%; border-radius:999px;}
.bs-track > i.fill{background:linear-gradient(90deg,#c99a2e,#8a5a08);}
.bs-track > i.done{background:linear-gradient(90deg,#14a37c,#0a5a45);}

/* 许愿者头像组 */
.bs-avs{display:flex; align-items:center; gap:6px; margin-top:9px; min-height:20px;}
.bs-avs .a{
  width:20px; height:20px; border-radius:50%; flex:none;
  background:var(--bs-line2); color:var(--bs-muted);
  display:flex; align-items:center; justify-content:center;
  font-size:10px; font-weight:600; overflow:hidden;
  box-shadow:0 0 0 1.5px var(--bs-card);
  margin-left:-6px;
}
.bs-avs .a:first-child{margin-left:0;}
.bs-avs .a img{width:100%; height:100%; object-fit:cover;}
.bs-avs small{font-size:11px; color:var(--bs-muted); margin-left:2px;}

/* 卡片底部操作区 */
.bs-bk .acts{margin-top:10px; display:flex; gap:6px;}
.bs-bk .acts .bs-btn{flex:1;}

/* ============================================================
   分区标题（书架的在读 / 在等）
   ============================================================ */
.bs-cat{
  display:flex; align-items:center; gap:10px;
  margin:30px 0 14px; font-size:15px; font-weight:600;
}
.bs-cat:first-of-type{margin-top:0;}
.bs-cat .dot{width:9px; height:9px; border-radius:50%; flex:none;}
.bs-cat .cnt{font-size:12.5px; color:var(--bs-muted); font-weight:400; margin-left:auto;}
.dot-teal{background:var(--bs-teal);} .dot-blue{background:var(--bs-blue);}
.dot-purple{background:var(--bs-purple);} .dot-amber{background:var(--bs-amber);}
.dot-red{background:var(--bs-red);}

/* ============================================================
   空状态 / 加载
   ============================================================ */
.bs-empty{
  background:var(--bs-card); border:1px solid var(--bs-line);
  border-radius:16px; box-shadow:var(--bs-sd);
  padding:48px 24px; text-align:center;
}
.bs-empty .art{width:150px; margin:0 auto 16px; opacity:.9;}
.bs-empty b{display:block; font-size:16px; font-weight:600;}
.bs-empty p{font-size:13px; color:var(--bs-muted); margin:7px 0 20px;}

.bs-skel{
  border-radius:12px; background:linear-gradient(100deg,#f1efe9 30%,#f8f7f4 50%,#f1efe9 70%);
  background-size:200% 100%; animation:bsShine 1.3s infinite linear;
}
@keyframes bsShine{from{background-position:150% 0}to{background-position:-50% 0}}

/* ============================================================
   轻提示
   ============================================================ */
.bs-toast{
  position:fixed; left:50%; bottom:34px; transform:translate(-50%,14px);
  z-index:9500; max-width:min(560px,calc(100vw - 40px));
  background:var(--bs-ink); color:#fff; font-size:13.5px; font-weight:600;
  padding:11px 20px; border-radius:11px; line-height:1.55;
  box-shadow:0 14px 34px -12px rgba(27,31,36,.5);
  opacity:0; visibility:hidden; transition:.22s; text-align:center;
}
.bs-toast.show{opacity:1; visibility:visible; transform:translate(-50%,0);}
.bs-toast.ok{background:#0a5a45;}
.bs-toast.err{background:#8a1b21;}
.bs-toast.gold{background:#6d4706;}

/* ============================================================
   AI 生成内容标识（法定要求，不可隐藏）
   ============================================================ */
.bs-ai{
  display:flex; align-items:flex-start; gap:8px;
  background:#f8f7f4; border:1px solid var(--bs-line);
  border-radius:10px; padding:9px 13px;
  font-size:11.5px; color:var(--bs-faint); line-height:1.6;
}
.bs-ai svg{flex:none; margin-top:2px; color:var(--bs-faint);}
.bs-ai b{color:var(--bs-ink2); font-weight:600;}

/* ============================================================
   页脚
   ============================================================ */
.bs-foot{
  max-width:1180px; margin:52px auto 0; padding:22px 20px 40px;
  border-top:1px solid var(--bs-line);
  font-size:12.5px; color:var(--bs-faint); line-height:2; text-align:center;
}
.bs-foot a{color:var(--bs-muted); text-decoration:none; margin:0 8px;}
.bs-foot a:hover{color:var(--bs-teal);}

/* ============================================================
   响应式
   ============================================================ */
@media (max-width:820px){
  .bs-nav .in{padding:10px 14px; gap:9px;}
  .bs-brand{font-size:14px;}
  .bs-brand .mark{height:16px;}
  /* 搜索框排到最后一行独占宽度 —— 否则会把「登录/注册」挤出屏幕右侧 */
  .bs-search{order:4; flex:1 1 100%; min-width:0;}
  .bs-navlinks{order:3; width:100%; overflow-x:auto;}
  .bs-hdright{margin-left:auto;}
  .bs-grid{grid-template-columns:repeat(auto-fill,minmax(146px,1fr)); gap:20px 14px;}
  .bs-cv{padding:15px 12px 12px 18px;}
  .bs-cv .ct{font-size:13.5px;}
  .bs-cv .ct::after{margin-top:7px; width:16px;}
}
