/* ============ class work · 设计系统（v3.25.1 起对齐「深蓝专业」风：海军蓝主色 + 白底大圆角 + 弥散轻阴影 + 强文字层级，参考用户提供的数据可视化 UI） ============ */
:root{
  --pri:#2C46A8; --pri-2:#1A237E; --pri-soft:#EDF1FB;
  --teal:#0EA5A5; --teal-soft:#E6F7F5;
  --amber:#F59E0B; --amber-soft:#FEF4E3;
  --rose:#E8455F; --rose-soft:#FDECEF;
  --green:#3FA45B; --green-soft:#EAF7EF;
  --accent:#06B6D4;                                  /* 家族强调色：极光青 */
  --ink:#1A2233; --ink-2:#4A5568; --ink-3:#94A0B8;   /* 标题近黑蓝 / 正文中灰 / 辅助浅灰，三级分明 */
  --bg:#F5F7FA; --card:#FFFFFF; --line:#EEF1F6;
  --r:18px; --r-s:11px; --r-pill:20px;
  --sh:0 4px 20px rgba(26,35,126,.05);               /* 弥散轻阴影（无描边，靠留白与阴影分层） */
  --sh-lg:0 10px 34px rgba(26,35,126,.14);
  --grad:linear-gradient(135deg,#2C46A8 0%,#1A237E 100%);
  /* 家族统一动效令牌 */
  --ease:cubic-bezier(.32,.72,0,1);
  --ease-spring:cubic-bezier(.34,1.4,.64,1);
  --dur-f:.15s; --dur:.25s;
  /* v3.26.0 字号阶梯（5 档锚点）：原来全站 49 个 font-size 值、相邻档差普遍只有 0.16–0.32px，
     肉眼分辨不出、还让「哪一级更大」失去意义。新增字号一律用这 5 档引用，不再写散值。 */
  --fs-xs:.75rem;    /* 12.0px 角标 / 底部导航 / 最小辅助 */
  --fs-sm:.82rem;    /* 13.1px 次要说明（.muted / .small 合并到这档） */
  --fs-md:.92rem;    /* 14.7px 正文 / 按钮 */
  --fs-lg:1.05rem;   /* 16.8px 卡片标题 */
  --fs-xl:1.25rem;   /* 20.0px 页面标题 */
}
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
/* v3.26.0：补 text-size-adjust —— 安卓 WebView / 微信内置浏览器默认会按容器宽度"字体放大"（Font Boosting），
   同一套 CSS 在不同页面字号忽大忽小。家长端 parent.html 一直有这行，主站漏了，现在对齐。 */
html{font-size:16px;-webkit-text-size-adjust:100%;text-size-adjust:100%}
/* v3.26.0：字体栈重排为「安卓优先」。原来 -apple-system/PingFang SC 在前，绝大多数安卓机全线落空、
   中文落到 Noto Sans CJK 合成字形（发闷、字重偏薄）——用户反馈的"字体不好看"主因就是这条。 */
body{font-family:system-ui,-apple-system,"Noto Sans SC","Source Han Sans SC","HarmonyOS Sans SC","PingFang SC","Microsoft YaHei",sans-serif;
  background:var(--bg);color:var(--ink);line-height:1.55;overscroll-behavior-y:none}
button{font-family:inherit;border:none;cursor:pointer;background:none;color:inherit}
input,textarea,select{font-family:inherit;font-size:1rem;color:var(--ink);
  border:1.5px solid var(--line);border-radius:var(--r-s);padding:.6rem .8rem;background:#fff;width:100%;outline:none;transition:border .15s}
input:focus,textarea:focus,select:focus{border-color:var(--pri)}
textarea{resize:vertical;min-height:80px}
a{color:var(--pri);text-decoration:none}
::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-thumb{background:#D5DBE8;border-radius:3px}

/* ---------- 布局骨架 ---------- */
#app{min-height:100vh}
.shell{display:flex;min-height:100vh}
.sidebar{display:none}
.main{flex:1;min-width:0;padding-bottom:calc(72px + env(safe-area-inset-bottom))}
.topbar{position:sticky;top:0;z-index:50;background:rgba(244,246,251,.88);backdrop-filter:blur(12px);
  padding:.9rem 1.1rem .6rem;display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;row-gap:.5rem}
/* v3.26.0：标题永不折行（原来 CJK 文本的 min-width:auto 会把「荣誉墙」压成「荣誉/墙」两行），过长给省略号 */
.topbar h1{font-size:var(--fs-xl);font-weight:700;letter-spacing:.5px;flex:0 1 auto;min-width:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.topbar #top-search{flex-shrink:0}
.topbar .sub{font-size:.78rem;color:var(--ink-3);font-weight:400;margin-left:.2rem}
.topbar .spacer{flex:1}
.page{padding:.4rem 1.1rem 1.5rem;max-width:1080px;margin:0 auto}

/* 底部标签栏（手机） */
.tabbar{position:fixed;left:0;right:0;bottom:0;z-index:60;display:flex;
  background:rgba(255,255,255,.94);backdrop-filter:blur(14px);
  border-top:1px solid var(--line);padding-bottom:env(safe-area-inset-bottom)}
.tabbar button{flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;padding:.5rem 0 .42rem;color:var(--ink-3);font-size:var(--fs-xs);transition:color .15s}
.tabbar button .ic{font-size:1.3rem;line-height:1.2}
.tabbar button.on{color:var(--pri);font-weight:600}
.tabbar button.on .ic{transform:scale(1.08)}

@media(min-width:900px){
  .tabbar{display:none}
  .sidebar{display:flex;flex-direction:column;width:224px;background:#fff;border-right:1px solid var(--line);
    position:fixed;top:0;bottom:0;left:0;z-index:60;padding:1.2rem .8rem}
  .sidebar .logo{display:flex;align-items:center;gap:.55rem;font-weight:700;font-size:1.12rem;padding:.3rem .6rem 1.1rem}
  .sidebar .logo .badge{width:34px;height:34px;border-radius:10px;background:var(--grad);display:flex;align-items:center;justify-content:center;font-size:1.1rem}
  .sidebar nav{display:flex;flex-direction:column;gap:.15rem;flex:1;overflow-y:auto}
  .sidebar nav button{display:flex;align-items:center;gap:.6rem;padding:.62rem .7rem;border-radius:10px;color:var(--ink-2);font-size:.92rem;text-align:left;width:100%}
  .sidebar nav button:hover{background:var(--bg)}
  .sidebar nav button.on{background:var(--pri-soft);color:var(--pri);font-weight:600}
  .sidebar .me{padding:.7rem;border-top:1px solid var(--line);font-size:.82rem;color:var(--ink-2);display:flex;align-items:center;gap:.5rem}
  .sidebar .me .av{width:30px;height:30px;border-radius:50%;background:var(--grad);color:#fff;display:flex;align-items:center;justify-content:center;font-size:.8rem;flex-shrink:0}
  .main{margin-left:224px;padding-bottom:2rem}
}

/* ---------- 通用组件 ---------- */
.card{background:var(--card);border-radius:var(--r);box-shadow:var(--sh);padding:1rem 1.1rem;margin-bottom:.85rem}
.card h3{font-size:var(--fs-lg);font-weight:700;margin-bottom:.65rem;display:flex;align-items:center;gap:.4rem}
.card h3 .more{margin-left:auto;font-size:.8rem;color:var(--pri);font-weight:500;cursor:pointer}
.row{display:flex;gap:.55rem;align-items:center;flex-wrap:wrap}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:.7rem}
@media(min-width:720px){.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:.85rem}
  .grid2w{display:grid;grid-template-columns:1fr 1fr;gap:.85rem;align-items:start}}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:.35rem;border-radius:12px;
  padding:.62rem 1.1rem;font-size:var(--fs-md);font-weight:600;transition:all .15s;background:var(--pri-soft);color:var(--pri)}
.btn:active{transform:scale(.97)}
.btn.pri{background:var(--grad);color:#fff;box-shadow:0 4px 14px rgba(79,124,255,.32)}
.btn.rose{background:var(--rose-soft);color:var(--rose)}
.btn.green{background:var(--green-soft);color:#16A34A}
.btn.amber{background:var(--amber-soft);color:#D97706}
.btn.gray{background:#F1F3F8;color:var(--ink-2)}
.btn.big{width:100%;padding:.85rem;font-size:1rem;border-radius:14px}
/* v3.26.0：min-height 补上项目自己定的「触控目标 ≥34px」（原来实测只有 31px，列表里的小按钮难点） */
.btn.sm{padding:.35rem .7rem;font-size:var(--fs-sm);border-radius:9px;min-height:34px}
.btn:disabled{opacity:.45;pointer-events:none}

.chip{display:inline-flex;align-items:center;gap:.25rem;padding:.28rem .7rem;border-radius:999px;font-size:.78rem;font-weight:500;background:#F1F3F8;color:var(--ink-2);cursor:pointer;transition:all .12s;border:1.5px solid transparent;user-select:none}
.chip.on{background:var(--pri-soft);color:var(--pri);border-color:var(--pri);font-weight:600}
.chip.rose.on{background:var(--rose-soft);color:var(--rose);border-color:var(--rose)}
.chip.green.on{background:var(--green-soft);color:#16A34A;border-color:var(--green)}

.tag{display:inline-block;padding:.12rem .5rem;border-radius:6px;font-size:.7rem;font-weight:600;line-height:1.5}
.tag.blue{background:var(--pri-soft);color:var(--pri)}
.tag.teal{background:var(--teal-soft);color:#0D9488}
.tag.amber{background:var(--amber-soft);color:#D97706}
.tag.rose{background:var(--rose-soft);color:var(--rose)}
.tag.green{background:var(--green-soft);color:#16A34A}
.tag.gray{background:#F1F3F8;color:var(--ink-2)}

.empty{text-align:center;padding:2.2rem 1rem;color:var(--ink-3);font-size:.88rem}
.empty .ic{font-size:2.4rem;display:block;margin-bottom:.5rem;opacity:.7}
/* v3.26.0：.muted(.8rem) 原来比 .small(.82rem) 还小 —— 类名暗示的层级正好相反，
   差 0.32px 又毫无视觉意义。两档合并到 --fs-sm，层级改为「靠颜色区分」而非靠字号。 */
.muted{color:var(--ink-3);font-size:var(--fs-sm)}
.small{font-size:var(--fs-sm)}
.bold{font-weight:700}
.mt{margin-top:.7rem}.mb{margin-bottom:.7rem}
.divider{height:1px;background:var(--line);margin:.7rem 0}

/* 表单 */
.field{margin-bottom:.75rem}
.field label{display:block;font-size:.82rem;font-weight:600;color:var(--ink-2);margin-bottom:.3rem}
.field .hint{font-size:.74rem;color:var(--ink-3);margin-top:.25rem}

/* 弹窗 */
.modal-mask{position:fixed;inset:0;background:rgba(20,26,45,.45);backdrop-filter:blur(3px);z-index:100;
  display:flex;align-items:flex-end;justify-content:center;animation:fadeIn .18s}
.modal{background:#fff;border-radius:20px 20px 0 0;width:100%;max-width:560px;max-height:88vh;overflow-y:auto;
  padding:1.2rem 1.2rem calc(1.4rem + env(safe-area-inset-bottom));animation:slideUp .22s cubic-bezier(.2,.8,.3,1)}
.modal .grab{width:38px;height:4px;border-radius:2px;background:#E3E7F0;margin:0 auto .9rem}
.modal h2{font-size:1.1rem;font-weight:700;margin-bottom:.9rem}
@media(min-width:900px){
  .modal-mask{align-items:center;padding:2rem}
  .modal{border-radius:20px;animation:popIn .2s cubic-bezier(.2,.8,.3,1)}
  .modal .grab{display:none}
}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@keyframes slideUp{from{transform:translateY(40px);opacity:0}to{transform:translateY(0);opacity:1}}
@keyframes popIn{from{transform:scale(.96);opacity:0}to{transform:scale(1);opacity:1}}

/* toast */
#toast-root{position:fixed;top:14px;left:50%;transform:translateX(-50%);z-index:200;display:flex;flex-direction:column;gap:.4rem;pointer-events:none}
.toast{background:rgba(30,36,51,.92);color:#fff;padding:.55rem 1rem;border-radius:12px;font-size:.86rem;
  animation:toastIn .22s;max-width:86vw;text-align:center;backdrop-filter:blur(6px)}
.toast.ok{background:rgba(22,163,74,.94)}.toast.err{background:rgba(225,29,72,.94)}
@keyframes toastIn{from{transform:translateY(-12px);opacity:0}to{transform:translateY(0);opacity:1}}

/* ---------- 登录页 ---------- */
.auth-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:1.5rem;
  background:linear-gradient(160deg,#2C46A8 0%,#1A237E 55%,#141C4D 110%)}
.auth-card{background:#fff;border-radius:24px;box-shadow:0 20px 60px rgba(20,30,80,.28);padding:2rem 1.6rem;width:100%;max-width:400px}
.auth-card .logo-big{width:64px;height:64px;border-radius:20px;background:var(--grad);display:flex;align-items:center;justify-content:center;font-size:2rem;margin:0 auto .9rem;box-shadow:0 8px 24px rgba(26,35,126,.35)}
.auth-card h1{text-align:center;font-size:1.4rem;letter-spacing:1px}
.auth-card .slogan{text-align:center;color:var(--ink-3);font-size:.84rem;margin:.3rem 0 1.4rem}
.auth-switch{text-align:center;margin-top:1rem;font-size:.84rem;color:var(--ink-3)}

/* ---------- 首页 ---------- */
.hero{background:var(--grad);border-radius:20px;padding:1.25rem 1.3rem;color:#fff;margin-bottom:.95rem;
  box-shadow:0 8px 26px rgba(79,124,255,.35);position:relative;overflow:hidden}
.hero::after{content:"";position:absolute;right:-30px;top:-30px;width:150px;height:150px;border-radius:50%;background:rgba(255,255,255,.09)}
.hero::before{content:"";position:absolute;right:34px;bottom:-52px;width:110px;height:110px;border-radius:50%;background:rgba(255,255,255,.07)}
.hero .date{font-size:.8rem;opacity:.85}
/* v3.1.1 主页hero右侧小机器人 */
.hero-bot{position:absolute;right:16px;top:16px;z-index:3;width:52px;height:52px;border-radius:50%;
  background:rgba(255,255,255,.2);border:1.5px solid rgba(255,255,255,.5);backdrop-filter:blur(6px);
  display:flex;align-items:center;justify-content:center;font-size:1.6rem;cursor:pointer;
  box-shadow:0 4px 14px rgba(0,0,0,.15);animation:botFloat 3s ease-in-out infinite;transition:transform .15s}
.hero-bot:active{transform:scale(.92)}
.hero-bot-tip{position:absolute;bottom:-20px;left:50%;transform:translateX(-50%);font-size:.62rem;white-space:nowrap;opacity:.85;font-weight:600}
@keyframes botFloat{0%,100%{margin-top:0}50%{margin-top:-5px}}
.hero .hello{font-size:1.35rem;font-weight:700;margin:.15rem 0 .85rem}
.hero .stats{display:flex;gap:1.4rem;position:relative;z-index:1}
.hero .stat b{font-size:1.3rem;display:block;line-height:1.2}
.hero .stat span{font-size:.72rem;opacity:.82}

.quick-entry{display:grid;grid-template-columns:repeat(auto-fit,minmax(70px,1fr));gap:.55rem;margin-bottom:.95rem}
.quick-entry button{background:#fff;border-radius:14px;border:1px solid var(--line);box-shadow:none;padding:.8rem .3rem;
  display:flex;flex-direction:column;align-items:center;gap:.35rem;font-size:.76rem;font-weight:600;color:var(--ink-2);transition:transform .12s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.quick-entry button:active{transform:scale(.95)}
.quick-entry .qic{width:40px;height:40px;border-radius:13px;display:flex;align-items:center;justify-content:center;font-size:1.2rem;flex-shrink:0}
.qic.b1{background:var(--pri-soft)}.qic.b2{background:var(--teal-soft)}.qic.b3{background:var(--amber-soft)}.qic.b4{background:var(--rose-soft)}

.alert-item{display:flex;align-items:center;gap:.6rem;padding:.62rem 0;border-bottom:1px solid var(--line);font-size:.88rem}
.alert-item:last-child{border-bottom:none}
.alert-item .dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.alert-item .tx{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.alert-item .btn{flex-shrink:0}

/* ---------- 时间线 ---------- */
.tl{position:relative;padding-left:1.15rem}
.tl::before{content:"";position:absolute;left:4.5px;top:6px;bottom:6px;width:2px;background:var(--line);border-radius:1px}
.tl-item{position:relative;padding:.45rem 0 .75rem}
.tl-item::before{content:"";position:absolute;left:-1.15rem;top:.72rem;width:11px;height:11px;border-radius:50%;
  background:#fff;border:3px solid var(--pri);z-index:1}
.tl-item.k-note::before{border-color:var(--pri)}
.tl-item.k-family::before{border-color:var(--teal)}
.tl-item.k-conduct::before{border-color:var(--amber)}
.tl-item.k-dorm::before{border-color:#8B5CF6}
.tl-item.k-incident::before{border-color:var(--rose)}
.tl-item.k-hw::before{border-color:#0EA5E9}
.tl-item.k-exam::before{border-color:var(--green)}
.tl-item .tl-head{display:flex;align-items:center;gap:.45rem;flex-wrap:wrap}
.tl-item .tl-time{font-size:.72rem;color:var(--ink-3)}
.tl-item .tl-text{font-size:.9rem;margin-top:.15rem;word-break:break-all}
.tl-imgs{display:flex;gap:.4rem;margin-top:.4rem;flex-wrap:wrap}
.tl-imgs img{width:64px;height:64px;object-fit:cover;border-radius:9px;cursor:pointer;border:1px solid var(--line)}

/* ---------- 学生 ---------- */
.stu-search{position:sticky;top:52px;z-index:20;padding:.3rem 0 .6rem;background:var(--bg)}
.stu-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:.6rem}
.stu-card{background:#fff;border-radius:14px;box-shadow:var(--sh);padding:.7rem .8rem;cursor:pointer;
  display:flex;align-items:center;gap:.6rem;transition:transform .12s;position:relative}
.stu-card:active{transform:scale(.97)}
.stu-card .av{width:36px;height:36px;border-radius:11px;display:flex;align-items:center;justify-content:center;
  font-size:.85rem;font-weight:700;color:#fff;flex-shrink:0}
.av.c0{background:linear-gradient(135deg,#60A5FA,#4F7CFF)}.av.c1{background:linear-gradient(135deg,#34D399,#14B8A6)}
.av.c2{background:linear-gradient(135deg,#FBBF24,#F59E0B)}.av.c3{background:linear-gradient(135deg,#F472B6,#EC4899)}
.av.c4{background:linear-gradient(135deg,#A78BFA,#8B5CF6)}.av.c5{background:linear-gradient(135deg,#38BDF8,#0EA5E9)}
.stu-card .nm{font-weight:600;font-size:.92rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.stu-card .fl{position:absolute;top:6px;right:7px;font-size:.68rem;display:flex;gap:2px}

/* 一生一档头 */
.dossier-head{background:var(--grad);border-radius:20px;padding:1.3rem;color:#fff;margin-bottom:.9rem;box-shadow:0 8px 26px rgba(79,124,255,.3);position:relative;overflow:hidden}
.dossier-head::after{content:"";position:absolute;right:-24px;top:-40px;width:140px;height:140px;border-radius:50%;background:rgba(255,255,255,.1)}
.dossier-head .nm{font-size:1.4rem;font-weight:700}
.dossier-head .meta{font-size:.8rem;opacity:.85;margin-top:.15rem}
.dossier-head .nums{display:flex;gap:1.2rem;margin-top:.8rem;position:relative;z-index:1}
.dossier-head .nums b{font-size:1.15rem;display:block}
.dossier-head .nums span{font-size:.7rem;opacity:.8}

/* ---------- 作业矩阵 ---------- */
.hw-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;border-radius:12px;border:1px solid var(--line)}
table.matrix{border-collapse:separate;border-spacing:0;width:100%;font-size:.82rem;background:#fff}
table.matrix th,table.matrix td{border-bottom:1px solid var(--line);border-right:1px solid var(--line);padding:.42rem .3rem;text-align:center;white-space:nowrap}
table.matrix th{background:#F7F9FD;font-weight:600;color:var(--ink-2);position:sticky;top:0;z-index:2}
table.matrix td:first-child,table.matrix th:first-child{position:sticky;left:0;background:#fff;z-index:1;font-weight:600;text-align:left;padding-left:.6rem;min-width:74px}
table.matrix th:first-child{background:#F7F9FD;z-index:3}
table.matrix tr:last-child td{border-bottom:none}
.g-cell{display:inline-flex;align-items:center;justify-content:center;min-width:30px;height:28px;border-radius:8px;font-weight:700;cursor:pointer;user-select:none;transition:transform .1s;padding:0 .25rem}
.g-cell:active{transform:scale(.9)}
.g-A{background:var(--green-soft);color:#16A34A}
.g-B{background:var(--pri-soft);color:var(--pri)}
.g-C{background:var(--amber-soft);color:#D97706}
.g-D{background:var(--rose-soft);color:var(--rose)}
.g-X{background:#F1F3F8;color:var(--ink-3);font-weight:500;font-size:.74rem}

/* ---------- 事件单 ---------- */
.inc-card{background:#fff;border-radius:var(--r);box-shadow:var(--sh);padding:.9rem 1rem;margin-bottom:.7rem;cursor:pointer;border-left:4px solid var(--pri)}
.inc-card.处理中{border-left-color:var(--amber)}
.inc-card.跟进观察{border-left-color:var(--pri)}
.inc-card.已归档{border-left-color:#C7CEDD}
.inc-card.待处理{border-left-color:var(--rose)}
.inc-card .t{font-weight:700;font-size:.95rem;display:flex;align-items:center;gap:.4rem}
.inc-card .m{font-size:.78rem;color:var(--ink-3);margin-top:.25rem;display:flex;gap:.6rem;flex-wrap:wrap}
/* v3.26.0：安全相关标记（疑似欺凌）原来 10.56px，手机上最难读的就是它 —— 提到 --fs-xs */
.bullying{background:var(--rose);color:#fff;font-size:var(--fs-xs);padding:.12rem .42rem;border-radius:5px;font-weight:700;animation:pulse 1.6s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.55}}

/* ---------- 座位 ---------- */
.seat-grid{display:grid;gap:6px;justify-content:center}
.seat{background:#fff;border:1.5px solid var(--line);border-radius:10px;min-height:44px;display:flex;align-items:center;justify-content:center;
  font-size:.78rem;font-weight:600;cursor:pointer;transition:all .12s;padding:.2rem;user-select:none;text-align:center;line-height:1.2}
.seat.sel{border-color:var(--pri);background:var(--pri-soft);box-shadow:0 0 0 3px rgba(79,124,255,.18)}
.seat.empty-seat{color:#C9D0DE;font-weight:400;background:#FAFBFE}
.seat.watch{border-color:#FCA5A5;background:var(--rose-soft)}
.podium{max-width:340px;margin:0 auto .8rem;background:linear-gradient(135deg,#DDE6FF,#E8E1FF);color:var(--pri);
  text-align:center;padding:.45rem;border-radius:10px;font-weight:700;font-size:.85rem;letter-spacing:6px}

/* ---------- 打印（A4） ---------- */
.print-area{display:none}
@media print{
  body{background:#fff}
  .sidebar,.tabbar,.topbar,.no-print{display:none !important}
  .main{margin:0;padding:0}
  .page{max-width:none;padding:0}
  .card{box-shadow:none;border:none;padding:0;margin:0}
  .print-area{display:block !important}
  .print-hide{display:none !important}
  @page{size:A4;margin:12mm}
}
.print-doc{font-family:"Songti SC","SimSun",serif;color:#000}
.print-doc h1{text-align:center;font-size:20pt;margin-bottom:4pt;font-family:"Heiti SC","SimHei",sans-serif}
.print-doc .p-sub{text-align:center;font-size:10.5pt;margin-bottom:10pt;color:#333}
.print-doc table{border-collapse:collapse;width:100%;font-size:10.5pt}
.print-doc th,.print-doc td{border:1px solid #000;padding:4pt 5pt;text-align:center}
.print-doc th{background:#eee;font-family:"Heiti SC","SimHei",sans-serif}
.print-doc .p-sec{font-size:12pt;font-weight:700;margin:10pt 0 4pt;font-family:"Heiti SC","SimHei",sans-serif}
.print-doc .p-item{font-size:10.5pt;line-height:1.7;border-bottom:1px dashed #999;padding:3pt 0}

/* 图片生成预览 */
.poster-preview{background:#fff;border-radius:14px;padding:.8rem;text-align:center;border:1px solid var(--line)}
.poster-preview img,.poster-preview canvas{max-width:100%;border-radius:8px;box-shadow:var(--sh)}

/* 分段器 */
.seg{display:flex;background:#EDF0F7;border-radius:12px;padding:3px;gap:3px}
.seg button{flex:1;padding:.45rem .3rem;border-radius:9px;font-size:.84rem;font-weight:600;color:var(--ink-2);transition:all .15s}
.seg button.on{background:#fff;color:var(--pri);box-shadow:0 1px 5px rgba(30,40,80,.12)}
/* 宠物页 5 个 tab 在手机上（≤430px）挤不下会被压扁/溢出，够不到的那个就跟"点不动"一样。
   改成横向可滑、按钮不压缩，保证每个 tab 都完整可点。 */
@media (max-width:430px){
  .pet-tabs{overflow-x:auto;-webkit-overflow-scrolling:touch;flex-wrap:nowrap;scrollbar-width:none}
  .pet-tabs::-webkit-scrollbar{display:none}
  .pet-tabs button{flex:0 0 auto;white-space:nowrap;font-size:.78rem;padding:.42rem .6rem}
}

/* 考勤格 */
.att-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(88px,1fr));gap:.5rem}
.att-cell{background:#fff;border:1.5px solid var(--line);border-radius:12px;padding:.55rem .4rem;text-align:center;cursor:pointer;transition:all .12s;user-select:none}
.att-cell .n{font-weight:600;font-size:.86rem}
.att-cell .s{font-size:.68rem;margin-top:.15rem;color:var(--green);font-weight:600}
.att-cell.s1{border-color:#FBBF24;background:var(--amber-soft)}.att-cell.s1 .s{color:#D97706}
.att-cell.s2{border-color:#38BDF8;background:#E8F6FE}.att-cell.s2 .s{color:#0284C7}
.att-cell.s3{border-color:var(--rose);background:var(--rose-soft)}.att-cell.s3 .s{color:var(--rose)}

/* 工具页宫格（v3.25 Telegram 风：扁平描边、统一高度、标签永不换行） */
.tool-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.55rem}
@media(min-width:720px){.tool-grid{grid-template-columns:repeat(4,1fr)}}
.tool-grid button{background:#fff;border-radius:14px;border:1px solid var(--line);box-shadow:none;padding:.8rem .3rem;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.4rem;font-size:.78rem;font-weight:600;color:var(--ink-2);transition:transform .12s;min-height:88px;max-width:100%}
.tool-grid button:active{transform:scale(.95)}
.tool-grid .tic{width:42px;height:42px;border-radius:13px;display:flex;align-items:center;justify-content:center;font-size:1.25rem;flex-shrink:0}
.tool-grid .tlabel{max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* v3.25.0 长按拖动排序（编辑态：磁贴微晃 + 底部完成条） */
.drag-edit .tool-grid button{animation:tile-wiggle 1.4s ease-in-out infinite;border-color:var(--pri);cursor:grab;touch-action:none}
.drag-edit .tool-grid button:nth-child(2n){animation-delay:.18s}
.drag-edit .tool-grid button:active{transform:none}
.drag-edit .drag-hint{visibility:hidden}
@keyframes tile-wiggle{0%,100%{transform:rotate(-.5deg)}50%{transform:rotate(.5deg)}}
.tool-drag-ghost{opacity:.25}
.drag-donebar{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(80px + env(safe-area-inset-bottom));z-index:120;
  display:flex;gap:.7rem;align-items:center;background:#fff;border-radius:var(--r-pill);box-shadow:var(--sh-lg);padding:.5rem .6rem .5rem 1rem;white-space:nowrap}
@media(prefers-reduced-motion:reduce){.drag-edit .tool-grid button{animation:none}}

.fade-in{animation:fadeIn .2s}
.spin{display:inline-block;width:1.1em;height:1.1em;border:2.5px solid var(--pri-soft);border-top-color:var(--pri);border-radius:50%;animation:sp .7s linear infinite}
@keyframes sp{to{transform:rotate(360deg)}}
.img-view{position:fixed;inset:0;background:rgba(0,0,0,.85);z-index:300;display:flex;align-items:center;justify-content:center;cursor:zoom-out}
.img-view img{max-width:96vw;max-height:92vh;border-radius:8px}

/* ---------- v1.3 侧边栏分组 ---------- */
.sidebar nav .nav-g{margin-bottom:.15rem}
.sidebar .nav-g-t{display:flex;align-items:center;gap:.35rem;width:100%;padding:.45rem .7rem;font-size:.74rem;
  font-weight:700;color:var(--ink-3);letter-spacing:1px;border-radius:8px}
.sidebar .nav-g-t:hover{background:var(--bg)}
.sidebar .nav-g-b button{padding:.5rem .7rem .5rem 1.1rem;font-size:.88rem}
/* 待办 */
.todo-item{display:flex;align-items:flex-start;gap:.6rem;padding:.6rem 0;border-bottom:1px solid var(--line)}
.todo-item:last-child{border-bottom:none}
.todo-item .ck{width:22px;height:22px;border-radius:7px;border:2px solid #C9D2E3;flex-shrink:0;margin-top:.1rem;
  display:flex;align-items:center;justify-content:center;font-size:.75rem;color:transparent;cursor:pointer;transition:all .12s}
.todo-item.done .ck{background:var(--green);border-color:var(--green);color:#fff}
.todo-item.done .tx{text-decoration:line-through;color:var(--ink-3)}
.todo-item .tx{flex:1;min-width:0;font-size:.9rem}
.pri-紧急重要{color:var(--rose);font-weight:700}
.pri-紧急{color:#D97706}
.pri-重要{color:var(--pri)}
/* 周计划板 */
.week-board{display:grid;grid-template-columns:repeat(5,1fr);gap:.5rem}
@media(max-width:719px){.week-board{grid-template-columns:1fr;}}
.week-col{background:#F7F9FD;border-radius:12px;padding:.55rem;min-height:90px}
.week-col h4{font-size:.78rem;color:var(--ink-2);margin-bottom:.4rem;text-align:center}
.week-col.today{background:var(--pri-soft)}
.week-col .wt{background:#fff;border-radius:8px;padding:.4rem .5rem;font-size:.78rem;margin-bottom:.35rem;box-shadow:var(--sh);cursor:pointer}
/* 月历 */
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}
.cal-cell{background:#fff;border-radius:10px;min-height:64px;padding:.3rem;font-size:.72rem;border:1.5px solid transparent;cursor:pointer}
.cal-cell .d{font-weight:700;color:var(--ink-2);font-size:.78rem}
.cal-cell.empty{background:transparent;cursor:default}
.cal-cell.has{border-color:var(--green-soft);background:var(--green-soft)}
.cal-cell.today{border-color:var(--pri)}
.cal-cell .ks{display:flex;flex-wrap:wrap;gap:2px;margin-top:.15rem}
.cal-cell .ks span{background:#fff;border-radius:4px;padding:0 3px;font-size:.62rem;color:var(--ink-2)}

/* ---------- v1.4 事件案卷 ---------- */
.stage-bar{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:2px;margin-top:.4rem}
.stage{font-size:.72rem;padding:.28rem .55rem;border-radius:8px;background:#F1F3F8;color:var(--ink-3);cursor:pointer;font-weight:600;transition:all .12s;white-space:nowrap}
.stage.done{background:var(--green-soft);color:#16A34A}
.stage.cur{background:var(--grad);color:#fff;box-shadow:0 3px 10px rgba(79,124,255,.35)}
.stage-arrow{color:#C9D0DE;font-size:.7rem}
.inc-card.已结案{border-left-color:#C7CEDD;opacity:.75}
/* 座位：同桌/小组模式 */
.desk-wrap{display:grid;gap:10px 14px;justify-content:center}
.desk{border:2px solid #DDE4F0;border-radius:12px;padding:5px;background:#FBFCFF;display:grid;gap:4px;position:relative}
.desk .grp-tag{position:absolute;top:-9px;left:8px;background:#fff;font-size:.6rem;color:var(--ink-3);padding:0 4px;border-radius:4px;border:1px solid var(--line)}
.desk.g0{border-color:#BFD4FF}.desk.g1{border-color:#B8EDE4}.desk.g2{border-color:#FFE0B8}.desk.g3{border-color:#F3D3FF}.desk.g4{border-color:#FFD3DC}.desk.g5{border-color:#D3E8B8}
.desk .seat{min-height:40px;border-width:1px}
.seat.locked{border-color:var(--amber);background:var(--amber-soft)}
.seat.locked::after{content:"🔒";font-size:.6rem;position:absolute;top:1px;right:2px}
.seat{position:relative}

/* ---------- v1.5 座位桌子模型 ---------- */
.desk{position:relative}
.desk.sel-desk{outline:3px solid var(--pri);outline-offset:1px}
.desk-menu{position:absolute;bottom:-7px;right:-6px;width:18px;height:18px;border-radius:50%;background:#fff;border:1px solid var(--line);
  font-size:.66rem;color:var(--ink-3);display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:var(--sh)}
.empty-slot{border:2px dashed #DDE4F0 !important;background:transparent !important;min-height:52px;display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:12px}
.empty-slot.slot-hot{border-color:var(--pri) !important;background:var(--pri-soft) !important}

/* ---------- v2.0 ---------- */
.gpick{position:relative;display:flex;flex-direction:column;align-items:center;padding:.4rem .2rem;border-radius:12px;
  border:1.5px solid transparent;cursor:pointer;background:#F7F9FD;transition:all .12s;min-width:0}
.gpick.on{border-color:var(--pri);background:var(--pri-soft);box-shadow:0 0 0 2px rgba(79,124,255,.15)}
/* 信号卡片 */
.sig{display:flex;gap:.6rem;align-items:flex-start;padding:.6rem 0;border-bottom:1px solid var(--line)}
.sig:last-child{border-bottom:none}
.sig .sic{width:34px;height:34px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:1rem;flex-shrink:0}
.sig.urgent .sic{background:var(--rose-soft)}.sig.warn .sic{background:var(--amber-soft)}
.sig.good .sic{background:var(--green-soft)}.sig.info .sic{background:var(--pri-soft)}
.sig .stx{flex:1;min-width:0;font-size:.85rem}
/* 班级纪事时间线 */
.chron{position:relative;padding-left:1.4rem}
.chron::before{content:"";position:absolute;left:7px;top:8px;bottom:8px;width:2.5px;background:linear-gradient(var(--pri),var(--teal));border-radius:2px}
.chron-item{position:relative;margin-bottom:1rem;background:#fff;border-radius:14px;box-shadow:var(--sh);padding:.8rem .9rem}
.chron-item::before{content:"";position:absolute;left:-1.72rem;top:1rem;width:13px;height:13px;border-radius:50%;background:#fff;border:3.5px solid var(--pri)}
.chron-item .ct{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap}
.chron-item .imgs{display:flex;gap:.35rem;margin-top:.5rem;flex-wrap:wrap}
.chron-item .imgs img{width:88px;height:88px;object-fit:cover;border-radius:10px;cursor:pointer}
/* 书架 */
.shelf{display:grid;grid-template-columns:repeat(auto-fill,minmax(74px,1fr));gap:.8rem;padding:1rem .4rem .4rem}
.spine{height:150px;border-radius:6px 9px 9px 6px;cursor:pointer;position:relative;box-shadow:3px 4px 10px rgba(20,30,60,.25), inset -3px 0 6px rgba(0,0,0,.18);
  display:flex;align-items:center;justify-content:center;transition:transform .15s;overflow:hidden}
.spine:hover{transform:translateY(-6px) rotate(-1deg)}
.spine .sv{writing-mode:vertical-rl;font-size:.78rem;font-weight:700;color:#fff;letter-spacing:2px;text-shadow:0 1px 2px rgba(0,0,0,.3);max-height:88%;overflow:hidden}
.spine.blue{background:linear-gradient(160deg,#4F7CFF,#3B5BDB)}.spine.teal{background:linear-gradient(160deg,#14B8A6,#0D9488)}
.spine.amber{background:linear-gradient(160deg,#F59E0B,#D97706)}.spine.rose{background:linear-gradient(160deg,#F43F5E,#E11D48)}
.spine.purple{background:linear-gradient(160deg,#8B5CF6,#7C3AED)}.spine.green{background:linear-gradient(160deg,#22C55E,#16A34A)}
.shelf-board{height:10px;background:linear-gradient(#C89B6C,#A97B4F);border-radius:3px;box-shadow:0 4px 8px rgba(0,0,0,.2);margin-top:-4px}
/* 宿舍床位图 */
.dorm-room{background:linear-gradient(#F7F9FD,#EFF3FA);border-radius:16px;padding:.9rem;border:1px solid var(--line)}
.bunk{background:#fff;border:1.5px solid #DDE4F0;border-radius:10px;padding:.35rem;box-shadow:var(--sh)}
.bunk .lvl{border:1px dashed #E3E7F0;border-radius:8px;padding:.35rem .4rem;margin:.2rem 0;display:flex;align-items:center;gap:.4rem;cursor:pointer;min-height:42px}
.bunk .lvl.up{background:#FBFCFF}
.bunk .bno{font-size:.62rem;color:var(--ink-3);font-weight:700;width:16px}
.bunk .bname{font-size:.82rem;font-weight:600;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bunk .lvl.has{border-style:solid;border-color:var(--pri);background:var(--pri-soft)}
.bunk .lvl.empty-b{color:#C9D0DE}
/* 值日v2 */
.duty-post{background:#fff;border-radius:12px;box-shadow:var(--sh);padding:.7rem .8rem;margin-bottom:.6rem}
.duty-post .ph{display:flex;align-items:center;gap:.4rem;font-weight:700;font-size:.9rem}

/* ============ v2.2：座位拖拽 / 轮换预览 / 信号忽略 / 时间线编辑 ============ */
.drag-ghost{position:fixed;z-index:9999;pointer-events:none;left:0;top:0;background:var(--pri);color:#fff;font-size:.78rem;font-weight:700;
  padding:.35rem .7rem;border-radius:10px;box-shadow:0 8px 20px rgba(79,124,255,.4);max-width:170px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.drop-hot{outline:2.5px dashed var(--pri)!important;outline-offset:2px;background:var(--pri-soft)!important}
.desk.locked-desk{border-color:#FBBF24;background:#FFFBEB}
.desk,.seat{touch-action:manipulation}
.rot-grid{display:grid;gap:5px;max-height:46vh;overflow-y:auto}
.rot-cell{border:1.5px solid var(--line);border-radius:9px;background:#fff;font-size:.7rem;padding:.45rem .3rem;text-align:center;cursor:pointer;
  min-height:38px;display:flex;align-items:center;justify-content:center;line-height:1.3;word-break:break-all}
.rot-cell.empty{color:#C9D0DE;background:#FAFBFE;cursor:default}
.rot-cell.locked{background:#FFFBEB;border-color:#FBBF24;cursor:default}
.rot-cell.sel{border-color:var(--pri);background:var(--pri-soft);box-shadow:0 0 0 3px rgba(79,124,255,.18)}
.rot-cell.zchg{border-color:#86EFAC;background:#F0FDF4}
.sig-x{border:none;background:transparent;color:var(--ink-3);font-size:.78rem;cursor:pointer;padding:.25rem .4rem;border-radius:7px;opacity:.5;flex-shrink:0;align-self:center}
.sig-x:active,.sig-x:hover{opacity:1;background:#F1F3F8}
.tl-edit{margin-left:auto;font-size:.7rem;color:var(--pri);cursor:pointer;white-space:nowrap;padding:0 .2rem;flex-shrink:0}

/* ============ v2.3：成绩卡片 / 书架拟真 / 档案页签 / 手机适配 / 全局质感 ============ */

/* ---- 成绩页 ---- */
.exam-strip{display:flex;gap:.45rem;overflow-x:auto;padding:.2rem .1rem .7rem;flex-wrap:nowrap;-webkit-overflow-scrolling:touch}
.ex-chip{flex-shrink:0;display:flex;align-items:center;gap:.3rem;background:#fff;border:1.5px solid var(--line);border-radius:12px;
  padding:.42rem .7rem;font-size:.8rem;font-weight:600;color:var(--ink-2);cursor:pointer;transition:all .15s;box-shadow:var(--sh)}
.ex-chip i{font-style:normal;font-size:.66rem;color:var(--ink-3);font-weight:400}
.ex-chip.on{background:var(--grad);color:#fff;border-color:transparent;box-shadow:0 4px 14px rgba(79,124,255,.35)}
.ex-chip.on i{color:rgba(255,255,255,.75)}
.x-head{border-radius:18px}
.x-stats{display:flex;gap:.4rem;margin-top:.8rem}
.x-stats>div{flex:1;background:var(--bg);border-radius:12px;padding:.55rem .3rem;text-align:center}
.x-stats b{display:block;font-size:1.12rem;font-variant-numeric:tabular-nums;color:var(--ink)}
.x-stats span{font-size:.66rem;color:var(--ink-3)}

/* ---- 书架拟真 ---- */
.shelf-room{background:linear-gradient(180deg,#F6F1E7 0%,#EDE4D3 100%);border:1px solid #E0D3BE;border-radius:20px;padding:1.1rem .9rem .9rem;position:relative;overflow:hidden}
.shelf-room::before{content:"";position:absolute;inset:0;background:radial-gradient(ellipse at 50% 0%,rgba(255,255,255,.5),transparent 60%);pointer-events:none}
.shelf-title{text-align:center;font-family:"Kaiti SC","KaiTi",serif;font-size:.95rem;color:#8A7350;letter-spacing:3px;margin-bottom:.9rem}
.shelf{display:flex;gap:.55rem;align-items:flex-end;padding:1.2rem .5rem 0;overflow-x:auto;min-height:178px;-webkit-overflow-scrolling:touch}
.spine{flex-shrink:0;width:52px;border-radius:4px 7px 7px 4px;cursor:pointer;position:relative;
  box-shadow:4px 5px 12px rgba(40,28,10,.35),inset -4px 0 7px rgba(0,0,0,.25),inset 3px 0 5px rgba(255,255,255,.28);
  display:flex;align-items:center;justify-content:center;transition:transform .18s ease,box-shadow .18s;transform-origin:bottom center}
.spine::before{content:"";position:absolute;left:5px;right:5px;top:9px;height:2px;background:rgba(255,215,130,.75);border-radius:2px;box-shadow:0 3px 0 rgba(255,215,130,.35)}
.spine::after{content:"";position:absolute;left:5px;right:5px;bottom:9px;height:2px;background:rgba(255,215,130,.75);border-radius:2px;box-shadow:0 -3px 0 rgba(255,215,130,.35)}
.spine:hover,.spine:active{transform:translateY(-12px) rotate(-1.5deg);box-shadow:6px 10px 20px rgba(40,28,10,.4),inset -4px 0 7px rgba(0,0,0,.25),inset 3px 0 5px rgba(255,255,255,.28)}
.spine .sv{writing-mode:vertical-rl;font-size:.76rem;font-weight:700;color:#fff;letter-spacing:3px;text-shadow:0 1px 3px rgba(0,0,0,.45);max-height:72%;overflow:hidden}
.spine .sno{position:absolute;bottom:16px;left:0;right:0;text-align:center;font-size:.56rem;color:rgba(255,255,255,.8);font-weight:700}
.shelf-board{height:13px;background:linear-gradient(180deg,#D9B98C 0%,#B98D5E 45%,#8F6840 100%);border-radius:3px 3px 5px 5px;
  box-shadow:0 6px 12px rgba(60,40,15,.35),inset 0 1px 0 rgba(255,255,255,.4);margin-top:-2px;position:relative}
.shelf-board::after{content:"";position:absolute;left:2%;right:2%;top:100%;height:5px;background:linear-gradient(180deg,rgba(60,40,15,.25),transparent);border-radius:0 0 6px 6px}
.shelf-meta{text-align:center;color:#9A845E;font-size:.72rem;margin-top:.75rem;letter-spacing:1px}
/* 封面视图 */
.shelf-covers{display:grid;grid-template-columns:repeat(auto-fill,minmax(118px,1fr));gap:.9rem;padding:.4rem .2rem}
.bcover{aspect-ratio:3/4.2;border-radius:5px 10px 10px 5px;cursor:pointer;position:relative;overflow:hidden;color:#fff;
  box-shadow:5px 7px 16px rgba(40,28,10,.32),inset -5px 0 9px rgba(0,0,0,.22),inset 4px 0 6px rgba(255,255,255,.2);
  display:flex;flex-direction:column;justify-content:space-between;padding:.85rem .7rem .7rem .9rem;transition:transform .18s}
.bcover:hover,.bcover:active{transform:translateY(-7px) rotate(-1deg)}
.bcover::before{content:"";position:absolute;left:7px;top:0;bottom:0;width:2px;background:rgba(255,215,130,.6)}
.bcover .ct{font-family:"Kaiti SC","KaiTi",serif;font-size:1rem;font-weight:700;letter-spacing:2px;line-height:1.5;text-shadow:0 1px 3px rgba(0,0,0,.35)}
.bcover .cm{font-size:.62rem;opacity:.82;line-height:1.5}
.bcover .cb{font-size:.6rem;letter-spacing:2px;opacity:.7;border-top:1px solid rgba(255,255,255,.3);padding-top:.4rem}
.bcover.blue{background:linear-gradient(155deg,#4F7CFF,#33489E)}.bcover.teal{background:linear-gradient(155deg,#14B8A6,#0B6E63)}
.bcover.amber{background:linear-gradient(155deg,#E8930C,#9A5B06)}.bcover.rose{background:linear-gradient(155deg,#E4405C,#8F1030)}
.bcover.purple{background:linear-gradient(155deg,#8B5CF6,#5227B0)}.bcover.green{background:linear-gradient(155deg,#22C55E,#0E7A38)}

/* ---- 个人档案页签 ---- */
/* v3.26.0：手机上 5 个页签需 ~400–440px、可用只有 ~340px，原来 flex:1 会把最后一个页签挤到横滑区外
   （而且它被压得很窄，看不出还能滑）。改 flex:0 0 auto：页签保持自然宽度、最后一个明显地"切一半"，
   这本身就是"还能往右滑"的提示（不用 mask 渐隐 —— 渐隐会把这个白色胶囊自己的圆角和阴影也一起淡掉）。 */
.dos-tabs{display:flex;gap:.4rem;background:#fff;border-radius:14px;padding:.3rem;box-shadow:var(--sh);margin-bottom:.85rem;overflow-x:auto;
  scrollbar-width:none}
.dos-tabs::-webkit-scrollbar{display:none}
.dos-tabs button{flex:0 0 auto;border-radius:10px;padding:.5rem .8rem;font-size:var(--fs-sm);color:var(--ink-2);font-weight:600;transition:all .15s;white-space:nowrap}
.dos-tabs button.on{background:var(--grad);color:#fff;box-shadow:0 3px 10px rgba(79,124,255,.3)}
.dossier-head{border-radius:22px;box-shadow:0 10px 32px rgba(79,124,255,.32)}
.dossier-head .nums{gap:.5rem!important}
.dossier-head .nums>div{flex:1;background:rgba(255,255,255,.14);border-radius:13px;padding:.5rem .3rem;text-align:center;backdrop-filter:blur(4px)}
.dossier-head .nums b{font-variant-numeric:tabular-nums}
@media(max-width:420px){
  .dossier-head .nums b{font-size:1rem}
  .dossier-head{padding:1.05rem}
}

/* ---- 座位手机适配（v3.15：列宽等分容器，彻底不重叠；不再自动缩放） ---- */
@media(max-width:719px){
  .desk-wrap{--seat-min:0px;width:100%;justify-content:stretch;padding-bottom:.5rem;gap:6px 6px;
    grid-template-columns:repeat(var(--desk-cols,4),minmax(0,1fr))!important}
  .desk-wrap>.desk,.desk-wrap>.empty-slot{min-width:0}
  .desk{padding:3px;border-radius:9px;gap:3px;min-width:0}
  .desk .seat{min-height:32px;font-size:.68rem;border-radius:7px;padding:.1rem;overflow:hidden;word-break:break-all;line-height:1.15}
  .desk .grp-tag{font-size:.52rem;padding:0 3px;top:-7px}
  .desk-menu{width:14px;height:14px;font-size:.55rem;bottom:-4px;right:-3px}
  .seat{min-height:32px;font-size:.68rem}
  .podium{max-width:none;min-width:60%;margin-bottom:.6rem;font-size:.8rem;letter-spacing:4px}
  .seat-viewport{max-height:58vh;padding:0}
  /* 列数越多字越小，避免名字换行把桌子撑高 */
  .desk-wrap.c5 .desk .seat{font-size:.62rem}
  .desk-wrap.c6 .desk .seat{font-size:.57rem}
  .desk-wrap.c6 .desk{padding:2px;gap:2px}
}

/* ---- v3.14 手机端「信息显示」通用优化：卡片/表格/标签更适配窄屏，长表格可横滑 ---- */
details>summary{list-style:none}
details>summary::-webkit-details-marker{display:none}
@media(max-width:719px){
  .card{padding:.85rem .85rem;border-radius:14px}
  /* v3.26.0：原来手机上把卡片标题压到 .93rem —— 比正文(.92rem)几乎一样大，标题层级整体塌掉。
     现在字号一律跟 --fs-* 令牌走，手机只调间距不缩字号。 */
  .card h3{font-size:var(--fs-lg);margin-bottom:.55rem}
  .dos-tabs button{padding:.45rem .6rem}
  table.matrix{font-size:.78rem}
  table.matrix th,table.matrix td{padding:.4rem .35rem}
  table.matrix td:first-child,table.matrix th:first-child{min-width:64px;padding-left:.45rem}
  .alert-item{font-size:.84rem;padding:.55rem 0}
  /* v3.26.0：原来手机上 .tag 缩到 .66rem(10.56px)，而同一层的 .chip 仍是 .78rem —— 层级错位且难读。收回桌面口径。 */
  .tag{font-size:.7rem;padding:.1rem .42rem}
  .hero{padding:1rem}
  .dossier-head .nums>div{padding:.45rem .2rem}
}

/* ---- 全局质感 ---- */
.card{box-shadow:0 2px 12px rgba(30,40,80,.055);border:1px solid rgba(237,240,246,.9);transition:box-shadow .2s}
.btn{transition:transform .12s ease,box-shadow .15s,background .15s}
.btn:active{transform:scale(.965)}
.btn.pri{box-shadow:0 3px 12px rgba(79,124,255,.28)}
.chip{transition:all .14s}
.hero{box-shadow:0 10px 32px rgba(79,124,255,.3);border-radius:22px}
.tag{font-weight:600}
.tl-item{transition:background .15s}
.matrix b,.x-stats b,.alert-item b{font-variant-numeric:tabular-nums}
.empty .ic{filter:grayscale(.15)}
h3{letter-spacing:.2px}

/* ============ v2.4 书房书架（参考 CodePen 拟真书架 + iReader 风格） ============ */
.study-room{position:relative;overflow:hidden;border-radius:22px;padding:1.15rem .55rem .9rem;border:1px solid #DCCDB2;
  background:radial-gradient(ellipse 120% 60% at 50% -8%, rgba(255,246,220,.75), transparent 58%),
             linear-gradient(180deg,#F0E6D2 0%,#E8DCC5 55%,#E0D2B8 100%);
  box-shadow:inset 0 2px 18px rgba(120,90,40,.12), 0 6px 24px rgba(80,60,30,.14)}
.shelf-title{text-align:center;font-family:"Kaiti SC","KaiTi",serif;font-size:.95rem;color:#8A7350;letter-spacing:4px;margin-bottom:.4rem;text-shadow:0 1px 0 rgba(255,255,255,.6)}
.bookcase{display:flex;flex-direction:column}
.shelf-row{display:flex;align-items:flex-end;gap:7px;padding:30px 16px 0;min-height:168px;overflow-x:auto;position:relative;-webkit-overflow-scrolling:touch}
.shelf-row::before{content:"";position:absolute;top:0;left:0;right:0;height:30px;
  background:linear-gradient(180deg,rgba(85,58,22,.32),rgba(85,58,22,0));pointer-events:none}
.shelf-plank{height:15px;margin:0 7px;position:relative;border-radius:3px;
  background:linear-gradient(180deg,#E0C296 0%,#C49A6C 38%,#9A7145 78%,#7E5A34 100%);
  box-shadow:0 8px 15px rgba(60,40,15,.42),inset 0 1.5px 0 rgba(255,240,210,.65),inset 0 -2px 3px rgba(50,30,10,.4)}
.shelf-plank::after{content:"";position:absolute;left:3%;right:3%;top:100%;height:7px;
  background:linear-gradient(180deg,rgba(60,40,15,.28),transparent);border-radius:0 0 8px 8px;pointer-events:none}
.book3d{position:relative;flex-shrink:0;cursor:pointer;border-radius:3px 7px 7px 3px;
  display:flex;align-items:center;justify-content:center;transform-origin:bottom center;
  transition:transform .25s cubic-bezier(.34,1.5,.64,1),box-shadow .25s,filter .25s;
  box-shadow:4px 5px 11px rgba(40,28,10,.42),inset -5px 0 9px rgba(0,0,0,.3),inset 3px 0 4px rgba(255,255,255,.26)}
.book3d:hover,.book3d:active{transform:translateY(-18px) rotate(-2.5deg) scale(1.04)!important;z-index:6;filter:brightness(1.07);
  box-shadow:8px 14px 24px rgba(40,28,10,.5),inset -5px 0 9px rgba(0,0,0,.3),inset 3px 0 4px rgba(255,255,255,.26)}
.book3d::before{content:"";position:absolute;left:6px;right:6px;top:10px;height:2.5px;border-radius:2px;
  background:linear-gradient(90deg,transparent,rgba(255,214,130,.85) 20%,rgba(255,236,190,.95) 50%,rgba(255,214,130,.85) 80%,transparent);
  box-shadow:0 4px 0 rgba(255,214,130,.35)}
.book3d::after{content:"";position:absolute;left:6px;right:6px;bottom:10px;height:2.5px;border-radius:2px;
  background:linear-gradient(90deg,transparent,rgba(255,214,130,.85) 20%,rgba(255,236,190,.95) 50%,rgba(255,214,130,.85) 80%,transparent);
  box-shadow:0 -4px 0 rgba(255,214,130,.35)}
.book3d .gloss,.bcover .gloss{position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:linear-gradient(102deg,transparent 28%,rgba(255,255,255,.2) 44%,rgba(255,255,255,.06) 54%,transparent 66%)}
.book3d .bt{writing-mode:vertical-rl;font-size:.76rem;font-weight:700;color:#fff;letter-spacing:3px;
  text-shadow:0 1px 3px rgba(0,0,0,.5);max-height:64%;overflow:hidden;position:relative;z-index:1}
.book3d .bv{position:absolute;bottom:17px;left:0;right:0;text-align:center;font-size:.56rem;color:rgba(255,230,170,.95);font-weight:700;z-index:1}
.book3d.blue{background:linear-gradient(158deg,#5B86FF 0%,#3B5BDB 55%,#2C42A8 100%)}
.book3d.teal{background:linear-gradient(158deg,#19C3B0 0%,#0D9488 55%,#0A6E63 100%)}
.book3d.amber{background:linear-gradient(158deg,#F0A020 0%,#C77408 55%,#95570A 100%)}
.book3d.rose{background:linear-gradient(158deg,#F04A68 0%,#C41E42 55%,#8F1030 100%)}
.book3d.purple{background:linear-gradient(158deg,#9668FF 0%,#6D3AED 55%,#4C22B8 100%)}
.book3d.green{background:linear-gradient(158deg,#2FD06B 0%,#15803D 55%,#0E5C2C 100%)}
.book3d.lean{transform:rotate(8deg) translateY(2px);margin-right:7px}
.deco{font-size:1.55rem;margin:0 3px 4px;flex-shrink:0;filter:drop-shadow(0 4px 4px rgba(60,40,15,.35))}
.shelf-meta{text-align:center;color:#96805A;font-size:.72rem;margin-top:.85rem;letter-spacing:1.5px}
.bcover{position:relative;box-shadow:6px 8px 18px rgba(40,28,10,.36),inset -6px 0 10px rgba(0,0,0,.24),inset 4px 0 6px rgba(255,255,255,.22)}
@media(max-width:520px){
  .shelf-row{padding:26px 10px 0;min-height:150px;gap:5px}
  .book3d .bt{font-size:.7rem;letter-spacing:2px}
}

/* ---------- v3.0 成绩模块：时间线 · 网格录入 · 保存条 ---------- */
.x-timeline{display:flex;flex-direction:column;gap:.1rem;margin-top:.3rem}
.xt-node{display:flex;align-items:center;gap:.7rem;padding:.62rem .5rem;border-radius:12px;cursor:pointer;transition:background .12s;border-left:3px solid transparent}
.xt-node:active{background:var(--bg)}
.xt-node.k-wk{border-left-color:#9AA3B5}
.xt-node.k-big{border-left-color:var(--pri)}
.xt-node.k-zk{border-left-color:var(--rose)}
.xt-dot{width:34px;height:34px;border-radius:11px;display:flex;align-items:center;justify-content:center;font-size:1rem;background:var(--bg);flex-shrink:0}
.xt-body{flex:1;min-width:0}
.xt-arrow{color:var(--ink-3);font-size:1.2rem;flex-shrink:0}
.x-grid .x-in{width:58px;padding:.28rem .1rem;border:1.5px solid transparent;border-radius:8px;text-align:center;background:transparent;font-size:.86rem;font-variant-numeric:tabular-nums;transition:border-color .12s,background .12s}
.x-grid .x-in:focus{border-color:var(--pri);background:#fff;outline:none}
.x-grid .x-in.bad{border-color:var(--rose);background:var(--rose-soft)}
.x-grid .x-rk{width:50px;color:var(--pri)}
.x-grid tbody tr:nth-child(even){background:rgba(244,246,251,.5)}
.x-savebar{position:sticky;bottom:calc(.6rem + env(safe-area-inset-bottom));z-index:30;display:none;align-items:center;justify-content:space-between;gap:.6rem;background:#fff;border-radius:14px;padding:.6rem .9rem;box-shadow:0 6px 24px rgba(30,40,80,.18);margin-top:.6rem;border:1.5px solid var(--pri-soft)}
.x-savebar.show{display:flex}
.x-savebar span:first-child{font-size:.82rem;font-weight:600;color:var(--pri)}

/* ============ v3.3 · 「一家亲」统一动画层（四应用同一套动效令牌） ============ */
@keyframes riseIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes checkPop{0%{transform:scale(0)}70%{transform:scale(1.25)}100%{transform:scale(1)}}
@keyframes shimmer{from{background-position:200% 0}to{background-position:-200% 0}}
@keyframes toastPop{0%{opacity:0;transform:translateY(-14px) scale(.94)}60%{transform:translateY(2px) scale(1.02)}100%{opacity:1;transform:translateY(0) scale(1)}}

/* 列表交错入场（视图重渲染即触发，延迟封顶防长列表拖沓） */
.card,.stu-card,.chron-item,.inc-card,.duty-post,.sig,.todo-item,.alert-item,.week-col .wt,.ex-chip{
  animation:riseIn .3s var(--ease) backwards}
.card:nth-of-type(1){animation-delay:.02s}.card:nth-of-type(2){animation-delay:.06s}
.card:nth-of-type(3){animation-delay:.10s}.card:nth-of-type(4){animation-delay:.14s}
.card:nth-of-type(n+5){animation-delay:.18s}
.stu-card:nth-child(2){animation-delay:.03s}.stu-card:nth-child(3){animation-delay:.06s}
.stu-card:nth-child(4){animation-delay:.09s}.stu-card:nth-child(5){animation-delay:.12s}
.stu-card:nth-child(6){animation-delay:.15s}.stu-card:nth-child(n+7){animation-delay:.18s}
.chron-item:nth-child(2){animation-delay:.05s}.chron-item:nth-child(3){animation-delay:.1s}
.chron-item:nth-child(n+4){animation-delay:.15s}
.todo-item:nth-child(2){animation-delay:.03s}.todo-item:nth-child(3){animation-delay:.06s}
.todo-item:nth-child(n+4){animation-delay:.09s}
.inc-card:nth-of-type(2){animation-delay:.05s}.inc-card:nth-of-type(n+3){animation-delay:.1s}

/* 按钮微交互：主按钮悬浮上浮 + 光晕（按压缩放已有） */
.btn.pri:hover{transform:translateY(-1px);box-shadow:0 6px 18px rgba(79,124,255,.42)}
.btn.pri:active{transform:scale(.965) translateY(0)}
.btn:hover{box-shadow:0 3px 12px rgba(30,40,80,.1)}

/* 班助特色：待办完成打勾弹跳 */
.todo-item.done .ck{animation:checkPop .35s var(--ease-spring)}
.todo-item .ck{transition:all .15s var(--ease-spring)}
/* 值日/事件阶段完成态弹跳 */
.stage.done{animation:riseIn .3s var(--ease)}
.g-cell{transition:transform .1s var(--ease-spring),background .15s}

/* Toast：弹入带回弹 */
.toast{animation:toastPop .32s var(--ease)}

/* 保存条滑入 */
.x-savebar.show{animation:riseIn .25s var(--ease)}

/* 侧边栏（桌面）激活项发光指示条 */
@media(min-width:900px){
  .sidebar nav button{transition:background .15s,color .15s,transform .15s var(--ease);position:relative}
  .sidebar nav button:hover{transform:translateX(2px)}
  .sidebar nav button.on::before{content:"";position:absolute;left:2px;top:50%;transform:translateY(-50%);
    width:3px;height:16px;border-radius:2px;background:var(--accent);box-shadow:0 0 8px var(--accent)}
}
/* 底部标签栏切换弹跳 */
.tabbar button .ic{transition:transform .2s var(--ease-spring)}
.tabbar button.on .ic{transform:scale(1.12)}

/* 骨架屏 */
.sk{border-radius:8px;background:linear-gradient(90deg,#EEF1F6 25%,#F7F9FC 50%,#EEF1F6 75%);
  background-size:200% 100%;animation:shimmer 1.3s infinite}
.sk-row{height:52px;margin-bottom:.5rem}

/* 无障碍：动效降级 */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
}

/* ============ v3.9 新增 ============ */
/* 考勤新状态：单节假 / 活动缺席 */
.att-cell.s4{border-color:#C4B5FD;background:#F3EEFF}.att-cell.s4 .s{color:#7C3AED}
.att-cell.s5{border-color:#CBD5E1;background:#F1F5F9}.att-cell.s5 .s{color:#64748B}

/* 圆形快捷入口（底栏中间主键 + 扇形菜单） */
.tabbar button.tab-mid{position:relative;color:var(--pri);font-weight:700}
.tabbar button.tab-mid .ic{display:flex;align-items:center;justify-content:center;width:46px;height:46px;border-radius:50%;background:var(--grad);color:#fff;font-size:1.35rem;margin-top:-18px;box-shadow:0 6px 18px rgba(79,124,255,.4);border:3px solid #fff}
.quick-mask{position:fixed;inset:0;z-index:120;background:rgba(20,26,40,.45);backdrop-filter:blur(2px);opacity:0;transition:opacity .2s}
.quick-mask.show{opacity:1}
.quick-ring{position:absolute;left:50%;bottom:26px;width:0;height:0}
.quick-item{position:absolute;left:-31px;bottom:-6px;width:62px;display:flex;flex-direction:column;align-items:center;gap:.15rem;background:#fff;border-radius:16px;padding:.45rem .2rem;box-shadow:var(--sh-lg);border:1px solid var(--line);opacity:0;transform:translate(0,0) scale(.4);transition:transform .38s cubic-bezier(.34,1.45,.64,1),opacity .2s}
/* v3.15 弹出动画：从底部圆键位置「炸开」到扇形位置（--tx/--ty 由 JS 注入），逐个错峰 */
.quick-mask.show .quick-item{opacity:1;transform:translate(var(--tx,0px),var(--ty,0px)) scale(1)}
/* v3.15 荣誉墙分类汇总徽章（点一下展开该类明细） */
.hw-cat{display:inline-flex;align-items:center;gap:.3rem;border:none;border-radius:10px;padding:.36rem .62rem;font-size:.78rem;font-weight:700;cursor:pointer;box-shadow:0 1px 4px rgba(30,40,80,.08);transition:transform .12s,box-shadow .15s}
.hw-cat b{background:rgba(255,255,255,.78);border-radius:6px;padding:0 .32rem;font-size:.74rem}
.hw-cat:active{transform:scale(.96)}
.hw-cat.on{transform:translateY(-1px);box-shadow:0 4px 12px rgba(30,40,80,.2)}
.hw-cat.on::after{content:"▾";margin-left:.1rem;font-size:.68rem}
.quick-item .qi-ic{font-size:1.3rem;line-height:1.2}
.quick-item .qi-n{font-size:.62rem;color:var(--ink-2);font-weight:600;white-space:nowrap}
.quick-item:active{transform-origin:center;filter:brightness(.95)}
.quick-edit,.quick-close{position:absolute;width:40px;height:40px;border-radius:50%;background:#fff;box-shadow:var(--sh-lg);font-size:1rem;display:flex;align-items:center;justify-content:center;border:1px solid var(--line)}
.quick-edit{left:74px;bottom:-14px}
.quick-close{left:-92px;bottom:-14px}

/* 录音转写：会议纪要式分段 */
.meet-seg{padding:.4rem .2rem;border-bottom:1px dashed var(--line)}
.meet-seg:last-child{border-bottom:none}
.meet-sp{display:flex;align-items:center;gap:.45rem;margin-bottom:.15rem}
.meet-tx{font-size:.86rem;line-height:1.7;color:var(--ink);padding-left:.2rem}

/* 事件时间线：处理环节分组 */
.stage-group{margin-bottom:.7rem}
.stage-g-title{display:flex;align-items:center;gap:.5rem;margin:.5rem 0 .3rem;padding-left:.1rem}
.stage-g-title::after{content:"";flex:1;height:1px;background:var(--line)}

/* 事件本杂志墙 */
.mag-wall{padding:.3rem 0 1rem}
.mag-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:.9rem;padding:.6rem .2rem}
.mag-card{cursor:pointer;transition:transform .18s cubic-bezier(.34,1.4,.64,1)}
.mag-card:active{transform:scale(.97)}
.mag-cover{position:relative;aspect-ratio:3/4;border-radius:12px;overflow:hidden;box-shadow:var(--sh-lg);background:linear-gradient(160deg,#4F7CFF,#7C5CFC)}
.mag-cover img{width:100%;height:100%;object-fit:cover;display:block}
.mag-cover.blue{background:linear-gradient(160deg,#4F7CFF,#7C5CFC)}
.mag-cover.teal{background:linear-gradient(160deg,#0D9488,#14B8A6)}
.mag-cover.amber{background:linear-gradient(160deg,#D97706,#F59E0B)}
.mag-cover.rose{background:linear-gradient(160deg,#E11D48,#FB7185)}
.mag-cover.purple{background:linear-gradient(160deg,#7C3AED,#A855F7)}
.mag-cover.green{background:linear-gradient(160deg,#15803D,#22C55E)}
.mag-gen{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.5rem;color:#fff;text-align:center;padding:.5rem}
.mag-vol{position:absolute;left:0;bottom:0;right:0;padding:.25rem .5rem;font-size:.64rem;color:#fff;background:linear-gradient(transparent,rgba(0,0,0,.55));text-align:right;letter-spacing:1px}
.mag-t{font-weight:700;font-size:.86rem;margin-top:.4rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mag-m{font-size:.7rem;color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* 座位表手机适配：平移缩放视口 */
.seat-viewport{overflow:auto;-webkit-overflow-scrolling:touch;touch-action:pan-x pan-y;max-height:72vh;padding:.2rem}
@media print{.seat-viewport{overflow:visible;max-height:none}}

/* ============ v3.9.1 樱花书屋门面（事件本书架） ============ */
.sakura-store{position:relative;overflow:hidden;border-radius:18px;padding:0 0 .6rem;
  background:
    radial-gradient(120% 60% at 50% -10%, rgba(255,220,200,.5), transparent 60%),
    repeating-linear-gradient(0deg, transparent 0 34px, rgba(120,50,35,.14) 34px 36px),
    repeating-linear-gradient(90deg, transparent 0 74px, rgba(120,50,35,.10) 74px 76px),
    linear-gradient(170deg, #D96D55 0%, #C75B4A 46%, #B34A3C 100%);
  box-shadow:var(--sh-lg)}
/* 屋檐遮阳篷：红白条纹+扇形垂边 */
.ss-awning{position:relative;height:34px;margin:0 10px;border-radius:10px 10px 0 0;
  background:repeating-linear-gradient(90deg,#E8564F 0 26px,#FFF6EE 26px 52px);
  box-shadow:0 4px 12px rgba(80,25,15,.35)}
.ss-awning::after{content:"";position:absolute;left:0;right:0;bottom:-13px;height:14px;
  background:radial-gradient(circle 13px at 13px -1px, #E8564F 12px, transparent 13px) 0 0/26px 14px repeat-x,
             radial-gradient(circle 13px at 13px -1px, #FFF6EE 12px, transparent 13px) 13px 0/26px 14px repeat-x}
/* 木牌店招 */
.ss-sign{text-align:center;margin:.9rem auto .3rem;width:max-content;max-width:92%;
  background:linear-gradient(160deg,#A0673F,#7A4A2B);color:#FFE9C9;padding:.5rem 1.6rem;border-radius:12px;
  font-family:'Kaiti SC','KaiTi',serif;font-size:1.22rem;font-weight:700;letter-spacing:5px;
  border:2px solid #5E3620;box-shadow:0 6px 16px rgba(60,25,10,.45), inset 0 1px 0 rgba(255,225,190,.35);position:relative;z-index:3}
.ss-sign::before,.ss-sign::after{content:"";position:absolute;top:-12px;width:4px;height:12px;background:#5E3620;border-radius:2px}
.ss-sign::before{left:16%}.ss-sign::after{right:16%}
/* 樱花枝 */
.ss-branch{position:absolute;top:26px;width:220px;max-width:42vw;z-index:4;pointer-events:none;filter:drop-shadow(0 3px 5px rgba(90,30,20,.25))}
.ss-bl{left:-8px}
.ss-br{right:-8px;transform:scaleX(-1)}
/* 飘落花瓣 */
.ss-petals{position:absolute;inset:0;z-index:5;pointer-events:none;overflow:hidden}
.ss-petals i{position:absolute;top:-14px;left:var(--x);width:9px;height:9px;border-radius:60% 0 60% 0;
  background:radial-gradient(circle at 30% 30%,#FFDDE6,#FFB7C5);opacity:.9;
  animation:ss-fall var(--rt,4s) linear infinite;animation-delay:var(--d);will-change:transform}
@keyframes ss-fall{
  0%{transform:translate(0,-4vh) rotate(0deg);opacity:0}
  8%{opacity:.95}
  100%{transform:translate(var(--sw,30px),105vh) rotate(420deg);opacity:.25}}
/* 橱窗 */
.ss-window{position:relative;z-index:2;margin:1.1rem 14px .2rem;padding:.9rem .7rem .2rem;
  background:linear-gradient(180deg, rgba(255,244,228,.94), rgba(250,235,214,.9));
  border:6px solid #7A4A2B;border-radius:14px;
  box-shadow:inset 0 2px 14px rgba(120,70,30,.25), 0 10px 26px rgba(60,25,10,.35)}
.ss-window::before{content:"";position:absolute;inset:-6px;border-radius:14px;pointer-events:none;
  border:2px solid #5E3620;box-shadow:inset 0 0 0 2px #A0673F}
.ss-shelf{display:flex;align-items:flex-end;gap:.55rem;padding:.5rem .6rem 0;min-height:110px;flex-wrap:wrap}
.ss-plank{height:12px;margin:0 .2rem;border-radius:4px;
  background:linear-gradient(180deg,#A0673F 0 40%,#7A4A2B 41% 100%);
  box-shadow:0 5px 10px rgba(70,30,10,.4), inset 0 1px 0 rgba(255,220,180,.4)}
/* 书 */
.ss-book{position:relative;flex-shrink:0;cursor:pointer;border-radius:5px 8px 8px 5px;
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;
  padding:.5rem .25rem .3rem;transition:transform .18s cubic-bezier(.34,1.4,.64,1), box-shadow .18s;
  box-shadow:2px 4px 10px rgba(70,30,10,.35), inset -3px 0 6px rgba(0,0,0,.18), inset 2px 0 0 rgba(255,255,255,.25)}
.ss-book:hover,.ss-book:active{box-shadow:3px 8px 18px rgba(70,30,10,.45), inset -3px 0 6px rgba(0,0,0,.18);filter:brightness(1.05)}
.ss-book.blue{background:linear-gradient(150deg,#5B86F5,#3B5BD9)}
.ss-book.teal{background:linear-gradient(150deg,#2BB3A3,#0E7C7B)}
.ss-book.amber{background:linear-gradient(150deg,#F2B544,#C77F1A)}
.ss-book.rose{background:linear-gradient(150deg,#F27D8D,#C93A55)}
.ss-book.purple{background:linear-gradient(150deg,#A78BFA,#6D43D8)}
.ss-book.green{background:linear-gradient(150deg,#5DC97F,#2C8A4E)}
.ss-gloss{position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:linear-gradient(105deg, rgba(255,255,255,.32) 0 14%, transparent 30%)}
.ss-bt{writing-mode:vertical-rl;font-family:'Kaiti SC','KaiTi',serif;font-weight:700;color:#FFF6E3;
  font-size:.8rem;letter-spacing:3px;text-shadow:0 1px 2px rgba(0,0,0,.35);margin-top:.15rem;max-height:72%;overflow:hidden}
.ss-bv{margin-top:auto;font-size:.56rem;color:rgba(255,246,227,.85);letter-spacing:1px;white-space:nowrap}
.ss-book.has-cover{background:#FFF8EC;border:1px solid #D9B98C;padding:.35rem .35rem .3rem;overflow:hidden}
.ss-book.has-cover img{width:100%;flex:1;min-height:0;object-fit:cover;border-radius:3px;display:block}
.ss-book.has-cover .ss-ct{writing-mode:horizontal-tb;font-size:.62rem;font-weight:700;color:#5E3620;
  margin-top:.25rem;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-shadow:none}
.ss-book.has-cover .ss-bv{color:#9A7B52}
.ss-deco{align-self:flex-end;font-size:1.3rem;margin:0 .2rem .1rem;filter:drop-shadow(0 2px 3px rgba(70,30,10,.3))}
/* 地面：石板 + 黑板 + 盆栽 */
.ss-ground{position:relative;z-index:2;display:flex;align-items:flex-end;justify-content:center;gap:1rem;
  margin:.7rem 10px 0;padding:.8rem .6rem .5rem;border-radius:10px;
  background:repeating-linear-gradient(90deg,#A8A29A 0 58px,#98928A 58px 62px);
  box-shadow:inset 0 6px 12px rgba(60,25,10,.3)}
.ss-board{background:#3A362F;border:6px solid #7A4A2B;border-radius:10px;padding:.1rem;
  box-shadow:0 6px 14px rgba(40,15,5,.4);max-width:280px;position:relative}
.ss-board::after{content:"";position:absolute;left:50%;bottom:-12px;transform:translateX(-50%);
  width:70%;height:12px;background:linear-gradient(180deg,rgba(40,15,5,.35),transparent)}
.sb-inner{padding:.55rem .9rem;color:#F4F1E4;font-size:.76rem;line-height:1.75;
  background:radial-gradient(120% 90% at 20% 10%, rgba(255,255,255,.06), transparent 55%)}
.sb-t{font-weight:700;font-size:.86rem;letter-spacing:2px;color:#FFE9A8;margin-bottom:.15rem}
.sb-l b{color:#9BE8B4}
.sb-tip{opacity:.75;font-family:'Kaiti SC','KaiTi',serif;font-size:.74rem;margin-top:.2rem}
.ss-pot{position:relative;width:44px;height:40px;flex-shrink:0}
.sp-body{position:absolute;left:4px;right:4px;bottom:0;height:24px;border-radius:4px 4px 10px 10px;
  background:linear-gradient(160deg,#C97B4A,#9A5530);box-shadow:0 4px 8px rgba(40,15,5,.4), inset 0 2px 0 rgba(255,210,170,.35)}
.sp-plant{position:absolute;left:50%;top:-6px;transform:translateX(-50%);font-size:1.5rem;filter:drop-shadow(0 2px 3px rgba(40,15,5,.35))}
@media (max-width:640px){
  .ss-sign{font-size:1rem;letter-spacing:3px;padding:.42rem 1rem}
  .ss-ground{flex-wrap:wrap}
  .ss-board{max-width:100%;flex:1 1 180px}
  .ss-petals i:nth-child(n+9){display:none}
  .ss-branch{top:20px}
}
@media (prefers-reduced-motion:reduce){
  .ss-petals{display:none}
}
@media print{.sakura-store{box-shadow:none}.ss-petals{display:none}}

/* ===== v3.10.0 成绩网格 Excel 化 ===== */
.x-grid th.sortable{cursor:pointer;user-select:none}
.x-grid th.sortable:active{background:#EDF1FA}
.x-grid .sarr{display:inline-block;margin-left:2px;font-size:.58rem;color:var(--pri)}
.x-grid tbody tr.row-hl>td{background:rgba(79,124,255,.045)}
.x-grid tbody td.col-hl{background:rgba(79,124,255,.045)}
.x-grid tbody tr:nth-child(even) td.col-hl,.x-grid tbody tr:nth-child(even).row-hl>td{background:rgba(79,124,255,.07)}
.x-grid .x-in.dirty{background:#FEF9C3;border-color:#FDE047}
.x-grid .x-in.cs-hi{color:#16A34A;font-weight:700;background:rgba(34,197,94,.09)}
.x-grid .x-in.cs-lo{color:#DC2626;background:rgba(239,68,68,.07)}
.x-grid .x-in.cs-hi.dirty,.x-grid .x-in.cs-lo.dirty{background:#FEF9C3}
.x-grid tbody tr.absent-row>td{background:#F3F4F6;color:#9CA3AF}
.x-grid tbody tr.absent-row .x-in{color:#9CA3AF}
.x-grid tbody tr.absent-row .x-tot{color:#9CA3AF}
.x-grid tfoot td,.x-grid tfoot th{position:sticky;bottom:0;z-index:2;background:#F7F9FD;border-top:1.5px solid var(--line);border-right:1px solid var(--line);padding:.4rem .3rem;text-align:center;font-size:.72rem;font-weight:700;color:var(--ink-2);font-variant-numeric:tabular-nums;white-space:nowrap}
.x-grid tfoot td:first-child{position:sticky;left:0;z-index:3;text-align:left;padding-left:.6rem}

/* ===== v3.10.0 图片查看器 ===== */
.img-view{cursor:default;flex-direction:column}
.img-view img{max-width:96vw;max-height:82vh;border-radius:8px;cursor:zoom-in;background:#111}
.img-view .iv-bar{position:absolute;top:0;left:0;right:0;display:flex;align-items:center;gap:.5rem;padding:calc(.6rem + env(safe-area-inset-top)) 1rem .6rem;background:linear-gradient(rgba(0,0,0,.55),transparent);z-index:2}
.img-view .iv-count{color:#fff;font-size:.8rem;font-variant-numeric:tabular-nums;min-width:3rem}
.img-view .iv-btn{background:rgba(255,255,255,.16);color:#fff;border:1px solid rgba(255,255,255,.25);border-radius:999px;padding:.35rem .8rem;font-size:.78rem;cursor:pointer;transition:background var(--dur,var(.15s)) var(--ease,ease)}
.img-view .iv-btn:hover,.img-view .iv-btn.on{background:rgba(255,255,255,.34)}
.img-view .iv-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:2;width:44px;height:64px;border:none;background:rgba(255,255,255,.1);color:#fff;font-size:1.8rem;border-radius:12px;cursor:pointer}
.img-view .iv-nav:hover{background:rgba(255,255,255,.24)}
.img-view .iv-nav.prev{left:.6rem}
.img-view .iv-nav.next{right:.6rem}

/* ---------- v3.20.0 首页改版：hero 双栏（诗词+统计 | 倒计时） ---------- */
.hero{display:flex;gap:.9rem;align-items:flex-start;flex-wrap:wrap}
.hero-main{flex:1;min-width:180px}
.hero-cd{position:relative;z-index:3;min-width:150px;max-width:220px;flex-shrink:0}
@media(max-width:640px){.hero-cd{max-width:none;width:100%;min-width:0}}
.poem{font-size:.82rem;opacity:.92;margin:.35rem 0 .5rem;font-style:italic;line-height:1.5}
.poem-a{font-style:normal;opacity:.75;font-size:.72rem;margin-left:.4rem}
.cd-item{display:flex;align-items:center;gap:.55rem;background:rgba(255,255,255,.16);border-radius:12px;
  padding:.42rem .6rem;margin-bottom:.4rem;cursor:pointer;backdrop-filter:blur(4px);transition:background .15s var(--ease)}
.cd-item:hover{background:rgba(255,255,255,.26)}
.cd-item .cd-ic{font-size:1.15rem}
.cd-tx{display:flex;flex-direction:column;line-height:1.25;min-width:0}
.cd-tx b{font-size:1.02rem;font-weight:700}
.cd-tx span{font-size:.7rem;opacity:.85;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cd-item.now{background:#FDE68A;color:#92400E}
.cd-item.now .cd-tx span{opacity:.9}
.cd-empty{background:rgba(255,255,255,.12);border:1px dashed rgba(255,255,255,.4);border-radius:12px;
  padding:.7rem;text-align:center;cursor:pointer;font-size:1.1rem}
.cd-empty span{display:block;font-size:.72rem;opacity:.85;margin-top:.15rem}
.cd-more{float:right;background:none;border:none;color:rgba(255,255,255,.8);font-size:1rem;cursor:pointer;padding:.1rem .5rem}
/* 信号折叠条（v3.25 收窄：单行紧凑，不再抢视觉） */
.sig-fold{padding:.5rem .9rem}
.sig-fold #hm-sigbar b{font-size:.85rem;white-space:nowrap}
.sig-fold #hm-sigbar .muted{font-size:.7rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sig-fold #hm-sigbar .more{font-size:.74rem}
/* ---------- v3.20.0 AI 小宠物 ---------- */
/* 立绘重画后同步放大：新初始款内容自占画布 85~89%（旧版只有 21~30%，所以「只有头、小小一只」），
   容器随之 44px→96px（32 的整数倍，像素款不糊）；hero 文案加右内边距让位，宠物不再是角落贴纸。
   宽度即点击热区（比立绘宽一点，手机上不误触）。 */
.pet{position:absolute;right:16px;top:8px;z-index:4;width:112px;text-align:center;cursor:pointer;user-select:none;-webkit-user-select:none;touch-action:manipulation}
.pet-body{width:128px;height:128px;margin:0 auto}/* 128=32×4=64×2：动物款(32 格)与人形 LPC 款(64 格)都取整数倍，pixelated 才不糊（44px=1.375×、96px 对 64 格＝1.5× 必糊） */
.hero .hero-main{padding-right:120px}
.pet-body svg,.pet-custom{width:100%;height:100%;display:block;pointer-events:none}
.pet-custom{object-fit:contain;border-radius:12px;animation:pet-breathe 3s var(--ease) infinite}
.pet-name{display:block;font-size:.66rem;opacity:.92;font-weight:700;margin-top:.15rem;color:#fff;text-shadow:0 1px 3px rgba(30,25,80,.35)}
.pet-bubble{position:absolute;right:132px;top:14px;background:#fff;color:var(--ink);font-size:.68rem;line-height:1.4;
  padding:.4rem .6rem;border-radius:10px 10px 2px 10px;box-shadow:var(--sh-lg);width:max-content;max-width:170px;
  animation:bubble-in .3s var(--ease-spring)}
@keyframes bubble-in{from{opacity:0;transform:scale(.6) translateY(6px)}to{opacity:1;transform:none}}
/* 美术升级 v3 §3.3（P3）：禁对位图做非整数倍 scale 动画——`image-rendering:pixelated` 只保证最近邻，
   scale(1.06) 这类非整数倍缩放下像素块粗细不均，是「呼吸时边缘抽动」的真元凶（MDN Crisp pixel art look）。
   呼吸感改 ±1–2px 竖向位移（位图动画只许 translate/opacity/steps，A12）；--pet-k=整数倍率，由 petKSync 写入。
   同一 keyframe 里先写固定值再写 calc(clamp)：老浏览器解析不了后者自动落回前者，位移永远在 1–2px 区间。 */
@keyframes pet-breathe{0%,100%{transform:translateY(0)}
  50%{transform:translateY(-2px);transform:translateY(calc(-1px*clamp(1,var(--pet-k,2),2)))}}
/* v3.20.1 瞳孔动画需要 transform-box:fill-box，否则 SVG 元素以画布原点缩放，眨眼看不见（"宠物不活跃"根因之一） */
.pet-pupil{transform-box:fill-box;transform-origin:center}
.pet-mouth{transform-box:fill-box;transform-origin:center}
/* ---------- v3.28.1 初始款「活着」：部件级微动（调研 vscode-pets：活的感觉来自行为，不是画得更细） ----------
   立绘里每个可动部件都是独立 <g class="pet-part-xx">，这里只给 1px 级幅度 + 错开的长周期，
   避免变成抖机灵；整只的 act-xx 动作仍挂 .pet-comp（装备跟随），与此处部件微动互不冲突。 */
.pet-eye,.pet-part-head,.pet-part-body,.pet-part-tail,.pet-part-arm,.pet-part-arm-l,.pet-part-arm-r,
.pet-part-leg,.pet-part-antenna{transform-box:fill-box}
.pet-eye{transform-origin:center}
/* 自动眨眼：5.6s 一次、闭 0.14s，左右眼同组同相位（两只不同步眨眼最假） */
.pet-comp>svg .pet-eye{animation:pet-eye-blink 5.6s var(--ease) infinite}
@keyframes pet-eye-blink{0%,94.6%{transform:scaleY(1)}96.4%{transform:scaleY(.1)}98.2%,100%{transform:scaleY(1)}}
/* 视线自己飘（好奇感）：位移 ≤1.5 viewBox 单位，96px 下约 1~2px */
.pet-iris,.pet-pupil{transform-box:fill-box}
.pet-comp>svg .pet-iris,.pet-comp>svg .pet-pupil{animation:pet-gaze 7.2s var(--ease) infinite}
@keyframes pet-gaze{0%,18%{transform:translate(0,0)}30%,46%{transform:translate(.9px,-.4px)}
  58%,74%{transform:translate(-.8px,.2px)}86%,100%{transform:translate(0,0)}}
/* 呼吸：只有胸腔 scaleY 1.014（96px 下 ≈1px），头不跟着胀才不会脱节 */
.pet-part-body{transform-origin:50% 100%;animation:pet-breath 3.1s var(--ease) infinite}
@keyframes pet-breath{0%,100%{transform:scaleY(1)}50%{transform:scaleY(1.014)}}
/* 头微偏：4.6s 一个来回，±1.4° */
.pet-part-head{transform-origin:50% 88%;animation:pet-head-idle 4.6s var(--ease) infinite}
@keyframes pet-head-idle{0%,100%{transform:rotate(0) translateY(0)}28%{transform:rotate(-1.4deg) translateY(-.25px)}66%{transform:rotate(1.1deg)}}
/* 尾巴慢摆：±8°，绕尾根。〔W3·P5〕两段式：steps(2,jump-none)=抽帧感；时长挂 --ic 派生（idle 3.2–4.8s 同谱），
   负 delay 按部件错相（尾 -1.1×ic、须 -0.7×ic、触角 -0.4×ic）——多宠同屏不再齐步走（v3 §3.4 P5）。 */
.pet-part-tail{transform-origin:8% 90%;animation:pet-tail-idle calc(var(--ic,3.6s)*.64) steps(2,jump-none) calc(var(--ic,3.6s)*-1.1) infinite}
@keyframes pet-tail-idle{0%,100%{transform:rotate(-4deg)}50%{transform:rotate(9deg)}}
/* 双手反相轻摆 + 腿随呼吸微沉 */
.pet-part-arm-l{transform-origin:86% 12%;animation:pet-arm-idle 3.4s var(--ease) infinite}
.pet-part-arm-r{transform-origin:14% 12%;animation:pet-arm-idle 3.4s var(--ease) infinite reverse}
@keyframes pet-arm-idle{0%,100%{transform:rotate(0)}50%{transform:rotate(3.2deg)}}
.pet-part-antenna{transform-origin:50% 100%;animation:pet-antenna-idle calc(var(--ic,3.6s)*.53) steps(2,jump-none) calc(var(--ic,3.6s)*-.4) infinite}
@keyframes pet-antenna-idle{0%,100%{transform:rotate(0)}35%{transform:rotate(-8deg)}70%{transform:rotate(6deg)}}
/* 落地感：立绘加极淡投影（配合 SVG 内接地渐变影），宠物才"站"在卡片上而不是贴纸。
   美术升级 v3 §3.3：滤镜宽度=calc(Npx×--pet-k)（先写固定值兜底，能解析 calc 的走 k 版） */
.pet-stage .pet-comp>svg{filter:drop-shadow(0 1.2px 1.4px rgba(30,20,60,.16))}
.pet-stage .pet-comp>svg{filter:drop-shadow(0 calc(.6px*var(--pet-k,2)) calc(.7px*var(--pet-k,2)) rgba(30,20,60,.16))}
.pet{padding:4px 0}/* 上下留白把热区撑满，宽度见上面的 .pet 主规则 */
/* P1 合成渲染（v9-44-pet.js petRender）：舞台=底宠+装备层+背景三层结构，动作类挂 .pet-comp（装备跟随一起动） */
/* 美术升级 v3 §3.3（P3）整数倍率：petKSync 测舞台 CSS 盒宽，按 k=max(1,round(容器宽×DPR/原生宽)) 把
   .pet-stage 锁成 native*k 的正方形（DPR 变化/resize 重算；设备像素倍率恒为整数——旧 pet-mini 44px
   =1.375× 就是「糊+抽动」的场景），并把 --pet-k（1 原生像素占多少 CSS 像素）发下去：
   装备层 width:% 乘上 native*k 后＝锚点整数格×k＝整数像素，层内非整数问题一并根治。
   发光/投影滤镜宽度全部 calc(Npx×k)——位图被放大 k 倍，滤镜不跟着走就会细得看不见/粗成一片糊。 */
.pet-stage{position:relative;width:100%;height:100%;margin:0 auto}
.pet-stage .pet-comp{position:absolute;inset:0}
/* 〔W2 · v3.1 G0-2〕层序全面改用 ULPC zPos 数域：底宠=100（body/head 域），
   前排装备=130（hat 域，高于发表 fg120），背层=8（低于发表 bg9）；
   P8 人形部件（.pet-part）按 parts_meta 的 zPos 9..130 逐件内联 z-index 插入同一数域。 */
.pet-stage .pet-px,.pet-stage .pet-custom,.pet-stage .pet-comp>svg{position:absolute;inset:0;width:100%;height:100%;z-index:100}
.pet-stage .pet-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:26%;image-rendering:pixelated;pointer-events:none;z-index:0}
.pet-stage .pet-layer{position:absolute;image-rendering:pixelated;image-rendering:crisp-edges;pointer-events:none;z-index:130}
.pet-stage .pet-layer.pet-behind{z-index:8}/* 翅膀/披风等背层垫在底宠（z100）与发表背景层（z9）之下 */
.pet-stage .pet-layer.pet-part{left:0;top:0;width:100%;height:100%}/* 部件=64 格整幅对齐覆盖层，z 由 JS 内联 */
/* 美术升级 v3 §3.2 脚下椭圆软投影件：暖棕 #8f6449 α≈100/255(.39)、径向羽化；
   尺寸=stage 百分比（stage 已由 petKApply 锁 native*k 整数倍，阴影随之取整）、零素材字节（镜像增量红线）；
   DOM 排在 pet-comp 前 → z-index:0 盖背景、垫底宠（z1）之下，只随 flag（palette_v2）出现 */
.pet-stage .pet-shadow{position:absolute;left:50%;bottom:4%;transform:translateX(-50%);width:58%;height:11%;
  border-radius:50%;pointer-events:none;z-index:0;
  background:radial-gradient(closest-side, rgba(143,100,73,.39), rgba(143,100,73,.2) 55%, rgba(143,100,73,0) 82%)}
.pet-spark{position:absolute;right:2%;top:-8%;font-size:.85em;font-style:normal;pointer-events:none;z-index:3;
  animation:pet-spark 2.4s var(--ease) infinite}
.pet-spark.sp2{right:auto;left:4%;top:4%;font-size:.68em;animation-delay:1.15s}
@keyframes pet-spark{0%{opacity:0;transform:scale(.4) translateY(3px)}35%{opacity:1}100%{opacity:0;transform:scale(1.15) translateY(-9px)}}
/* 雪夜背景：动态飘雪（bg_snow 素材 fx=snow，前端按锚点表加 class） */
.pet-stage.pet-snow::after{content:"";position:absolute;inset:0;border-radius:26%;pointer-events:none;z-index:2;opacity:.95;
  background-image:radial-gradient(2px 2px at 20% 30%,#fff 60%,transparent 61%),radial-gradient(2px 2px at 55% 12%,#fff 60%,transparent 61%),
  radial-gradient(2px 2px at 78% 42%,#fff 60%,transparent 61%),radial-gradient(1.6px 1.6px at 38% 62%,#fff 60%,transparent 61%);
  animation:pet-snowfall 3.6s linear infinite}
@keyframes pet-snowfall{from{background-position:0 -25%,0 -12%,0 -32%,0 -18%}to{background-position:0 125%,0 112%,0 132%,0 118%}}
/* 〔W3·P4 场景纵深〕对齐 vscode-pets 六层实测（背景特效/背景/宠物/气泡/前景特效/前景）：
   z 域（与 W2 的 ULPC zPos 数域同居一套尺子）：bg0 → 暗角1 → 光斑40 → 部件9..120/底宠100/前排装备130
   → 前景遮挡 fg200 → 花瓣/前景特效210；气泡（.pet-bubble）在页面层不受 stage z 管辖。
   前景遮挡件 fg.png=tools/pet_fg.py 生成的板色剪影（叶/桌沿/浪/雪堆压底部 1–3 行，中上带留空断言），
   只在声明了 fg 的背景出现；光斑=CSS 径向暖斑慢层 α16%（10–20% 带内）steps(2) 漂移；
   暗角=径向 inset α10%（8–12% 带内）；花瓣=飘落点阵慢层 α14%（樱花款专属，替代 snow 位）。 */
.pet-stage::before{content:"";position:absolute;inset:0;border-radius:26%;pointer-events:none;z-index:1;
  background:radial-gradient(120% 92% at 50% 36%,transparent 52%,rgba(23,16,28,.10) 100%)}
.pet-stage .pet-spotlight{position:absolute;inset:0;border-radius:26%;pointer-events:none;z-index:40;opacity:.16;
  background:radial-gradient(34% 26% at 22% 24%,#ffe8a7,transparent 72%),radial-gradient(30% 22% at 76% 62%,#fcd9bd,transparent 74%);
  animation:pet-spot-drift calc(var(--ic,3.6s)*3.4) steps(2,jump-none) infinite}
@keyframes pet-spot-drift{0%,100%{transform:translate(0,0)}50%{transform:translate(2px,-1px)}}
.pet-stage .pet-fg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:26%;
  image-rendering:pixelated;pointer-events:none;z-index:200}
.pet-stage .pet-lightmask{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:26%;pointer-events:none;
  z-index:45;opacity:.5}/* 〔W3·P4〕Kenney 光遮罩（CC0，白+α）：窗光/树影压背景层，宠物在光下不入光斑本体 */
.pet-stage.pet-petals::after{content:"";position:absolute;inset:0;border-radius:26%;pointer-events:none;z-index:210;opacity:.14;
  background-image:radial-gradient(3px 2px at 18% 22%,#f0b9c5 60%,transparent 61%),radial-gradient(2px 2px at 52% 8%,#f0b9c5 60%,transparent 61%),
    radial-gradient(3px 2px at 74% 34%,#db70a9 60%,transparent 61%),radial-gradient(2px 2px at 36% 58%,#f0b9c5 60%,transparent 61%);
  animation:pet-snowfall 9s linear infinite}
/* 〔W3·P5〕idle 两段式：整台慢速 1px 两档起伏（steps(2,jump-none)=换帧感而非滑动；A12 只许 translate）；
   --ic=3.2~4.8s 按宠物 id 定档（petRender 写内联，多宠不同相防同步——方案"本周可做"条）。 */
.pet-stage .pet-comp{animation:pet-2f var(--ic,3.6s) steps(2,jump-none) infinite}
@keyframes pet-2f{0%,100%{transform:translateY(0)}50%{transform:translateY(-1px)}}
.pet-menu-stage{width:128px;height:128px;margin:0 auto;position:relative}
/* 〔W3·版式七件·B线参考假设〕容器不裸放白卡：三段纵向渐变+顶部径向光斑+同色系深描边+圆角14
   （渐变/光斑/圆角类来自截图目测＝参考假设，**人眼截图复核未闭环**，回退=删本块与季节角标）；
   色值全部板内（smoke ㊱ lint）；UI 深色文字取宠物板色禁纯黑纯灰：--pet-ink #5a4632 / --pet-ink2 #3e4a59。
   脚下椭圆投影（已在 P2）、前后景遮挡（已在 P4 fg）、光斑慢层（已在 P4 spotlight）——七件齐。 */
:root{--pet-ink:#5a4632;--pet-ink2:#3e4a59}
.pet-page-hero{position:relative;border:6px solid #8f6449;border-radius:14px;color:var(--pet-ink);
  border-image:url(/pet/kenney/panel0.png) 12 fill;border-image-outset:0;
  background:linear-gradient(180deg,#fff6e5 0%,#fbf3e3 46%,#f6e7bf 100%)}/* 〔W3·P4〕Kenney Pixel Adventure 画框件（CC0，1 块 32px 面板 border-image 九宫） */
.pet-page-hero::after{content:"";position:absolute;inset:0;border-radius:14px;pointer-events:none;
  background:radial-gradient(58% 34% at 50% 0%,rgba(255,232,167,.42),transparent 72%)}
.pet-season{position:absolute;top:.5rem;right:.7rem;z-index:5;font-size:1rem;font-style:normal;opacity:.85;pointer-events:none}
.pet-page-hero .muted,.pet-page-hero .small{color:var(--pet-ink2)}
.pet-body.act-blink .pet-pupil,.pet-comp.act-blink .pet-pupil{animation:pet-blink .45s steps(1) 3}
@keyframes pet-blink{50%{transform:translateY(1px) scaleY(.15)}}
/* 〔W3·P5 两段式全库推广〕act-* 全表 A12 化：位图只许 translate/opacity/steps——
   旧 look/wag/wave/sleepy 挂 rotate、hop/heartbeat 挂 scale（作用在 .pet-comp＝旋转/缩放位图，像素边缘重采样发糊，
   与 W1 修的 scale(1.06) 呼吸同族病）。全部换位移等价动作 + steps(2,jump-none) 两档离散
   （像素"换帧感"来自档位而不是缓动曲线）。 */
.pet-body.act-look,.pet-comp.act-look{animation:pet-look 1.2s steps(2,jump-none)}
@keyframes pet-look{0%,100%{transform:translateX(0)}30%{transform:translateX(-2px)}70%{transform:translateX(2px)}}
.pet-body.act-hop,.pet-comp.act-hop{animation:pet-hop .5s steps(2,jump-none) 2}
@keyframes pet-hop{0%,100%{transform:translateY(0)}35%{transform:translateY(-14px)}70%{transform:translateY(0)}}
.pet-body.act-wag,.pet-comp.act-wag{animation:pet-wag 1.2s steps(2,jump-none)}
@keyframes pet-wag{0%,100%{transform:translateX(0) translateY(0)}25%{transform:translateX(-3px) translateY(-2px)}75%{transform:translateX(3px) translateY(-2px)}}
.pet-body.act-double,.pet-comp.act-double{animation:pet-hop .5s steps(2,jump-none) 4}
/* v3.20.1：不再用位移类 walk 动画——视觉位置离开点击热区会导致"点不到" */
.pet-body.act-spin,.pet-comp.act-spin{animation:pet-spin 1s steps(2,jump-none)}
@keyframes pet-spin{0%{transform:translateX(0);opacity:1}25%{transform:translateX(9px);opacity:.72}
  50%{transform:translateX(0);opacity:.5}75%{transform:translateX(-9px);opacity:.72}100%{transform:translateX(0);opacity:1}}
.pet-skin{width:52px;height:52px;border-radius:12px;border:2px solid var(--line);background:var(--bg);cursor:pointer;padding:3px}
.pet-skin.on{border-color:var(--pri);box-shadow:0 0 0 2px var(--pri-soft)}
.pet-skin svg{width:100%;height:100%}
@media(prefers-reduced-motion:reduce){.pet-body,.pet-custom,.pet-bubble,.pet-comp,.pet-spark,.pet-stage.pet-snow::after,
  .pet-stage .pet-spotlight,.pet-stage.pet-petals::after,
  .pet-comp>svg .pet-eye,.pet-comp>svg .pet-iris,.pet-comp>svg .pet-pupil,.pet-part-body,.pet-part-head,
  .pet-part-tail,.pet-part-arm-l,.pet-part-arm-r,.pet-part-antenna{animation:none!important}}
/* ---------- v3.28.0 宠物「续火花」：像素立绘 / 角标 / 飘字 / 宠物页 ---------- */
.pet-px{image-rendering:pixelated;image-rendering:crisp-edges;width:100%;height:100%;display:block;pointer-events:none;object-fit:contain}
.pet-badge{position:absolute;left:-6px;top:-8px;background:linear-gradient(135deg,#FFE9A8,#FFC94D);color:#7A4E00;
  font-size:.56rem;font-weight:800;padding:.14rem .4rem;border-radius:999px;box-shadow:0 2px 6px rgba(0,0,0,.15);
  white-space:nowrap;letter-spacing:.02em;transition:filter .3s}
.pet-badge.dim{filter:grayscale(.85);opacity:.75}
.pet-badge.on{position:static;display:inline-block}
#pet-float{position:fixed;left:50%;top:14%;transform:translate(-50%,-8px);z-index:9999;background:linear-gradient(135deg,#FFF3D6,#FFE3A8);
  color:#7A4E00;font-weight:800;font-size:.95rem;padding:.45rem 1rem;border-radius:999px;box-shadow:0 6px 20px rgba(122,78,0,.28);
  opacity:0;pointer-events:none;transition:opacity .3s,transform .3s}
#pet-float.show{opacity:1;transform:translate(-50%,0)}
/* 宠物页（P0 基础版 + P1 合成舞台） */
.pet-page-hero{display:flex;gap:.9rem;align-items:center}
.pet-big{position:relative;width:128px;height:128px;flex-shrink:0;display:flex;align-items:flex-end;justify-content:center;background:
  radial-gradient(circle at 50% 34%,#FBF7FF,#EAE0FF 72%);border-radius:26px;overflow:visible;box-shadow:inset 0 -6px 14px rgba(120,90,220,.10)}
.pet-big .pet-stage{width:100%;height:100%}
.pet-big .pet-comp{inset:0}/* 内层＝128px：32 与 64 两种画布都取整数倍（旧 96px 对 64 格人形＝1.5× 必糊）；.pet-big 本身 overflow:visible，帽子/光环越界仍不被裁 */
.pet-big .pet-badge{position:absolute;left:-4px;top:-6px;z-index:4}
.pet-xpbar{height:8px;border-radius:999px;background:var(--line);overflow:hidden;margin:.45rem 0 .2rem}
.pet-xpbar div{height:100%;border-radius:999px;background:linear-gradient(90deg,#FFC94D,#FF9F43)}
.stat-row{display:flex;gap:.6rem;flex-wrap:wrap}
.stat-row .stat{flex:1;min-width:52px;text-align:center;background:#fff;border:1px solid var(--line);border-radius:12px;padding:.35rem .1rem}
.stat-row .stat b{display:block;font-size:.95rem}
.stat-row .stat span{font-size:.6rem;color:var(--muted)}
.shop-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:.55rem}
/* 皮肤 SVG 去重后的定义容器：0 尺寸，只当图库用，不参与布局 */
.pet-defs{position:absolute;width:0;height:0;overflow:hidden;pointer-events:none}
/* 图鉴/商店一屏几十格：屏幕外的那些先别渲染（手机上点 tab 不再像"进不去"） */
.shop-grid{content-visibility:auto;contain-intrinsic-size:auto 200px}
.pet-balance{font-size:.92rem}
.pet-balance b{color:#8A5A00;font-size:1.1rem}
.shop-item{position:relative;border:1px solid var(--line);border-radius:14px;padding:.55rem .3rem;text-align:center;cursor:pointer;transition:transform .15s var(--ease-spring),border-color .15s;background:#fff}
.shop-item:active{transform:scale(.96)}
.shop-item.owned{opacity:.72}
.shop-item.wearing{opacity:1;border-color:var(--pri);box-shadow:0 0 0 2px var(--pri-soft)}
.shop-item.poor{opacity:.5}
.shop-item .sic{display:flex;height:40px;align-items:center;justify-content:center;font-size:1.5rem;margin-bottom:.2rem}
.shop-item .sic img{width:36px;height:36px}
.shop-item .pet-mini{width:64px;height:64px;margin:0 auto .25rem}
.shop-item b{display:block;font-size:.72rem}
.shop-item .small{display:block;font-size:.62rem}
.shop-item .si-btn{display:inline-block;margin-top:.3rem;font-size:.62rem;font-weight:700;color:#fff;background:var(--pri);border-radius:999px;padding:.13rem .55rem}
.shop-item.owned .si-btn{background:#fff;color:var(--pri);border:1px solid var(--pri)}
.shop-item.poor .si-btn{background:var(--line);color:var(--muted)}
.shop-item .si-tag{position:absolute;left:4px;top:4px;font-size:.55rem;background:#EFE9FF;color:var(--pri);border-radius:8px;padding:.06rem .32rem;font-weight:700}
.shop-item .si-tag.on{background:#E9FBE9;color:#16A34A}
.milestones{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:.5rem}
.mile{display:flex;gap:.5rem;align-items:center;border:1px solid var(--line);border-radius:12px;padding:.5rem .6rem;background:#fff;opacity:.72}
.mile.on{opacity:1;border-color:var(--green);background:linear-gradient(160deg,#F4FFF5,#E9FBE9)}
.mile span:first-child{font-size:1.2rem}
.mile b{font-size:.78rem;display:block}

/* ================= v3.28 P2 宠物：10 动作 + 酷炫特效 + 庆祝/图鉴/串门（方案 §6.2/§6.4，全 CSS 零素材） ================= */
/* —— 新增 6 个动作（眨眼/歪头/蹦跳/转圈 P0 已有；比心/招手/举牌/打瞌睡/打滚/摆尾 补齐）—— */
.pet-body.act-roll,.pet-comp.act-roll{animation:pet-roll 1.55s steps(2,jump-none)}
@keyframes pet-roll{0%{transform:translateX(0) translateY(0)}30%{transform:translateX(11px) translateY(-7px)}
  60%{transform:translateX(-11px) translateY(-3px)}100%{transform:translateX(0) translateY(0)}}
.pet-body.act-tail,.pet-comp.act-tail{animation:pet-tail .85s steps(2,jump-none) 2}
@keyframes pet-tail{0%,100%{transform:translateX(0)}25%{transform:translateX(3px)}75%{transform:translateX(-3px)}}
.pet-body.act-heart,.pet-comp.act-heart{animation:pet-heartbeat .85s steps(2,jump-none) 2}
@keyframes pet-heartbeat{0%,100%{transform:translateY(0)}30%{transform:translateY(-4px)}48%{transform:translateY(0)}62%{transform:translateY(-2px)}}
.pet-comp.act-heart::after{content:"💗";position:absolute;left:50%;top:-12%;z-index:4;font-size:.8em;font-style:normal;pointer-events:none;
  animation:pet-heartfloat 1.75s var(--ease) forwards}
@keyframes pet-heartfloat{0%{opacity:0;transform:translateX(-50%) translateY(8px) scale(.4)}35%{opacity:1}100%{opacity:0;transform:translateX(-50%) translateY(-16px) scale(1.15)}}
.pet-body.act-wave,.pet-comp.act-wave{animation:pet-wave .62s steps(2,jump-none) 3}
@keyframes pet-wave{0%,100%{transform:translateX(0)}25%{transform:translateX(3px)}75%{transform:translateX(-2px)}}
.pet-body.act-sign,.pet-comp.act-sign{animation:pet-signpop 1s var(--ease-spring)}
@keyframes pet-signpop{0%,100%{transform:translateY(0)}22%{transform:translateY(-11px)}55%{transform:translateY(-5px)}}
.pet-comp.act-sign::after{content:"🪧";position:absolute;right:-4%;top:-18%;z-index:4;font-size:.85em;font-style:normal;pointer-events:none;
  animation:pet-signshow 1s var(--ease-spring)}
@keyframes pet-signshow{0%{opacity:0;transform:scale(.2) rotate(24deg)}40%{opacity:1;transform:scale(1.1) rotate(-4deg)}75%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.9)}}
.pet-body.act-sleep,.pet-comp.act-sleep{animation:pet-sleepy 3s steps(2,jump-none)}
@keyframes pet-sleepy{0%{transform:translateY(0)}30%,75%{transform:translate(2px,3px)}100%{transform:translateY(0)}}
.pet-comp.act-sleep::after{content:"💤";position:absolute;right:2%;top:-12%;z-index:4;font-size:.8em;font-style:normal;pointer-events:none;opacity:0;
  animation:pet-zzz 3s var(--ease)}
@keyframes pet-zzz{0%{opacity:0;transform:translateY(4px) scale(.5)}45%{opacity:1;transform:translateY(-7px) scale(1)}100%{opacity:0;transform:translateY(-17px) scale(1.25)}}
/* 像素底宠的眨眼：整身下沉 2px 一档（scaleY 是竖向缩放位图，A12 禁；steps(1) 单档=换帧感） */
.pet-comp.act-blink .pet-px{animation:pet-blink-px .5s steps(1) 2}
@keyframes pet-blink-px{45%{transform:translateY(2px)}}
/* —— 火花光环（3/30/100 天 → 微光 / 火焰环 / 金色流光）—— */
.pet-stage.aura-glow .pet-comp::before{content:"";position:absolute;inset:-10%;border-radius:50%;pointer-events:none;z-index:0;
  background:radial-gradient(circle,rgba(255,201,77,.3),rgba(255,201,77,0) 70%);animation:aura-pulse 3s var(--ease) infinite}
@keyframes aura-pulse{0%,100%{opacity:.55;transform:scale(1)}50%{opacity:1;transform:scale(1.07)}}
.pet-stage.aura-fire .pet-comp::before{content:"";position:absolute;inset:-14%;border-radius:50%;pointer-events:none;z-index:0;
  background:conic-gradient(from 0deg,#FF9F43,#FFC94D,#FF6B35,#FFC94D,#FF9F43);
  -webkit-mask:radial-gradient(circle,transparent 56%,#000 63%,#000 74%,transparent 80%);
  mask:radial-gradient(circle,transparent 56%,#000 63%,#000 74%,transparent 80%);
  animation:aura-spin 4.5s linear infinite}
@keyframes aura-spin{to{transform:rotate(360deg)}}
.pet-stage.aura-gold .pet-comp::before{content:"";position:absolute;inset:-16%;border-radius:50%;pointer-events:none;z-index:0;
  background:conic-gradient(from 0deg,#FFF3B0,#FFD24D,#FFA94D,#FFD24D,#FFF9D9,#FFC94D,#FFF3B0);
  -webkit-mask:radial-gradient(circle,transparent 52%,#000 60%,#000 76%,transparent 82%);
  mask:radial-gradient(circle,transparent 52%,#000 60%,#000 76%,transparent 82%);
  animation:aura-spin 3.2s linear infinite;filter:drop-shadow(0 0 6px rgba(255,210,90,.8))}
.pet-stage.aura-gold .pet-comp::before{filter:drop-shadow(0 0 calc(3px*var(--pet-k,2)) rgba(255,210,90,.8))}
/* —— [G1 M12] 发光态（免疫段表现层）：暖金呼吸 halo，写在 .pet-stage 自身伪元素上，
   不占 .pet-comp::before（那层是火花光环的地盘）；只加不减——掉光回常态，绝无惩罚视觉。 —— */
.pet-stage.glow-on{position:relative}
.pet-stage.glow-on::before{content:"";position:absolute;inset:6%;border-radius:50%;z-index:0;pointer-events:none;
  background:radial-gradient(circle,rgba(255,236,150,.42),rgba(255,214,102,.14) 55%,rgba(255,214,102,0) 72%);
  animation:pet-glow-breath 2.8s var(--ease) infinite}
@keyframes pet-glow-breath{0%,100%{opacity:.55;transform:scale(1)}50%{opacity:1;transform:scale(1.09)}}
/* —— [G1 M3] 今日任务环：本周 8 格进度条（第一格＝白送的赋予进度） —— */
.ring-week{display:flex;gap:5px;align-items:center;margin:.35rem 0}
.ring-week i{width:20px;height:8px;border-radius:4px;background:#e6e2f2;transition:background .3s}
.ring-week i.on{background:linear-gradient(90deg,#f7a35c,#ffd166)}
.ring-week span{margin-left:.3rem}
/* —— [G1 M2] 火花被召回横幅 + [M13] 代班日记 —— */
.shield-recall{background:linear-gradient(135deg,#FFF6E3,#FFEBD2);border:1px solid #F5DCAE;border-radius:10px;
  padding:.5rem .7rem;font-size:.86rem;color:#8a5a12;font-weight:600}
.pet-diary .diary-tx{background:#FBF8F1;border-left:3px solid #C9B37E;border-radius:0 10px 10px 0;
  padding:.6rem .8rem;font-size:.9rem;color:#5c4a22;margin:.2rem 0}
/* —— [G1 M1] 班级花园：学期格子花境（一格一天，32px 素材缩到 20px） —— */
.garden-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(24px,1fr));gap:4px;max-width:560px;margin:.4rem 0}
.garden-grid .gc{width:20px;height:20px;border-radius:5px;image-rendering:pixelated}
.garden-grid .gc.blank{background:#efeef6;border:1px dashed #d9d5e8}
.garden-grid .gc.leaf{opacity:.55}
.garden-legend{gap:.7rem;flex-wrap:wrap;color:var(--muted);font-size:.78rem}
.garden-legend img{width:13px;height:13px;vertical-align:-2px;margin-right:3px;image-rendering:pixelated}
.pet-glow-note{background:linear-gradient(135deg,#FFFBEA,#FFF3D6);border:1px solid #F2E2AC;color:#7a5a10}
/* —— 等级光效 Lv30/45/60 逐级增强（只加 filter，不占 .pet-comp 的 animation，避免压住 act-* 动作）——
   美术升级 v3 §3.3：像素发光带宽度=calc(Npx×--pet-k)（1px 滤镜 × 整数倍率；先固定值兜底，下同）。—— */
.pet-stage.lvfx1 .pet-comp{filter:drop-shadow(0 0 3px rgba(255,201,77,.55))}
.pet-stage.lvfx1 .pet-comp{filter:drop-shadow(0 0 calc(1.5px*var(--pet-k,2)) rgba(255,201,77,.55))}
.pet-stage.lvfx2 .pet-comp{filter:drop-shadow(0 0 5px rgba(124,92,252,.5)) drop-shadow(0 0 2px rgba(255,201,77,.6))}
.pet-stage.lvfx2 .pet-comp{filter:drop-shadow(0 0 calc(2.5px*var(--pet-k,2)) rgba(124,92,252,.5)) drop-shadow(0 0 calc(1px*var(--pet-k,2)) rgba(255,201,77,.6))}
.pet-stage.lvfx3 .pet-comp{filter:drop-shadow(0 0 8px rgba(255,175,60,.8)) drop-shadow(0 0 16px rgba(124,92,252,.4))}
.pet-stage.lvfx3 .pet-comp{filter:drop-shadow(0 0 calc(4px*var(--pet-k,2)) rgba(255,175,60,.8)) drop-shadow(0 0 calc(8px*var(--pet-k,2)) rgba(124,92,252,.4))}
/* —— 完全体光效（进化 Lv35，evo-final 由 pet.evo 驱动；同上只用 filter/::after 呼吸）—— */
.pet-stage.evo-final .pet-comp{filter:drop-shadow(0 0 6px rgba(255,215,80,.75))}
.pet-stage.evo-final .pet-comp{filter:drop-shadow(0 0 calc(3px*var(--pet-k,2)) rgba(255,215,80,.75))}
.pet-stage.evo-final::after{content:"";position:absolute;inset:16%;border-radius:50%;pointer-events:none;z-index:3;
  background:radial-gradient(circle,rgba(255,225,120,.28),rgba(255,225,120,0) 68%);animation:aura-pulse 3.4s var(--ease) infinite}
/* —— 传说皮肤：入场动画 + 环绕粒子（皮肤稀有度来自商店数据，无写死 id）—— */
.pet-stage.skin-legend{animation:legend-stage-in 1.05s var(--ease-spring)}
@keyframes legend-stage-in{0%{transform:scale(.25) rotate(-14deg);opacity:0;filter:brightness(2.6) saturate(1.6)}55%{transform:scale(1.12) rotate(3deg);opacity:1}100%{transform:scale(1) rotate(0);filter:brightness(1)}}
.pet-pc{position:absolute;z-index:4;font-style:normal;pointer-events:none;font-size:.72em;opacity:0;animation:pc-float 2.6s var(--ease) infinite}
.pet-pc.p1{left:4%;top:6%}.pet-pc.p2{right:6%;top:-4%;animation-delay:1.1s}.pet-pc.p3{left:38%;top:-10%;animation-delay:.5s}
@keyframes pc-float{0%{opacity:0;transform:translateY(6px) scale(.5)}30%{opacity:1}100%{opacity:0;transform:translateY(-14px) scale(1.1)}}
/* —— 传说背景：动态星光粒子（bg-legend 由背景稀有度驱动；bg_snow 飘雪沿用 P1 的 fx=snow）—— */
.pet-pcbg{position:absolute;z-index:1;width:4px;height:4px;border-radius:50%;background:#FFF6C9;box-shadow:0 0 6px 2px rgba(255,240,170,.8);opacity:0;pointer-events:none;animation:bg-tw 2.8s var(--ease) infinite}
.pet-pcbg.b1{left:14%;top:22%}.pet-pcbg.b2{right:18%;top:38%;animation-delay:.9s}.pet-pcbg.b3{left:42%;top:64%;animation-delay:1.7s}
@keyframes bg-tw{0%,100%{opacity:0;transform:scale(.4)}40%{opacity:.95;transform:scale(1)}70%{opacity:.4;transform:scale(.8)}}
/* —— 里程碑庆祝全屏层 —— */
#pet-celebrate{position:fixed;inset:0;z-index:9998;display:flex;align-items:center;justify-content:center;overflow:hidden;
  background:rgba(40,30,8,.38);backdrop-filter:blur(2px);animation:cel-in .3s ease}
@keyframes cel-in{from{opacity:0}to{opacity:1}}
.cel-card{position:relative;z-index:2;background:linear-gradient(165deg,#FFFDF2,#FFF1CF);border:1px solid #F3E3B3;border-radius:22px;
  padding:1.15rem 1.3rem;max-width:330px;width:86%;box-shadow:0 18px 50px rgba(120,80,0,.3);text-align:center;animation:cel-pop .5s var(--ease-spring)}
@keyframes cel-pop{0%{transform:scale(.5) translateY(30px);opacity:0}70%{transform:scale(1.05)}100%{transform:scale(1);opacity:1}}
.cel-big{font-size:2.5rem;animation:cel-bounce 1.1s var(--ease-spring) infinite}
@keyframes cel-bounce{0%,100%{transform:translateY(0) scale(1)}45%{transform:translateY(-10px) scale(1.12)}}
.cel-item{display:flex;flex-direction:column;gap:.1rem;border:1px solid #F0DFAE;background:#fff;border-radius:14px;padding:.5rem .7rem;margin-top:.5rem;text-align:left}
.cel-item b{font-size:.9rem}.cel-item span{font-size:.72rem;color:var(--muted)}
#pet-celebrate .cf{position:absolute;top:-8vh;left:var(--x);width:9px;height:13px;border-radius:2px;background:var(--c);z-index:1;
  animation:cf-fall 3s var(--ease) var(--d) infinite}
@keyframes cf-fall{0%{transform:translateY(-10vh) rotate(0);opacity:0}8%{opacity:1}100%{transform:translateY(115vh) rotate(560deg);opacity:.5}}
/* —— 图鉴（未拥有真图+锁）—— */
.shop-item.dex{cursor:default}
.shop-item.dex.locked{opacity:.85;background:linear-gradient(180deg,#FBFAFF,#F3F1FA)}
.shop-item.dex.locked img,.shop-item.dex.locked .pet-mini{filter:grayscale(.7) brightness(.95);opacity:.6}
.shop-item.dex.locked .sic{filter:grayscale(.6);opacity:.65}
.dex-lock{position:absolute;right:5px;top:4px;font-size:.9rem;filter:drop-shadow(0 1px 2px rgba(0,0,0,.25))}
/* —— 成就墙 —— */
.ach-item{display:flex;gap:.55rem;align-items:flex-start;border:1px solid var(--line);border-radius:14px;padding:.55rem .65rem;background:#fff;margin-bottom:.45rem}
.ach-item.on{border-color:var(--green);background:linear-gradient(160deg,#F6FFEE,#EDFAE9)}
.ach-ic{font-size:1.25rem;line-height:1.3}
.ach-tx{flex:1;min-width:0}.ach-tx b{font-size:.82rem;display:block}
.ach-bar{height:6px;border-radius:999px;background:var(--line);overflow:hidden;margin:.25rem 0 .1rem}
.ach-bar div{height:100%;border-radius:999px;background:linear-gradient(90deg,#FFC94D,#FF9F43)}
/* —— 串门社交 —— */
.soc-inbox{border-color:var(--pri)!important;background:linear-gradient(165deg,#F8F5FF,#EFE9FF)}
.soc-row{display:flex;gap:.6rem;align-items:center;border:1px solid var(--line);border-radius:14px;padding:.5rem .6rem;background:#fff;margin-bottom:.45rem}
.soc-mini{width:64px;height:64px;flex-shrink:0;cursor:pointer}
.soc-tx{flex:1;min-width:0}.soc-tx b{font-size:.85rem}
.soc-offlink{color:var(--pri);cursor:pointer;font-weight:700}
.soc-visit-stage{position:relative;height:150px;margin:.4rem 0 .6rem;border-radius:18px;background:linear-gradient(165deg,#F4F8FF,#EAF2FF);overflow:hidden}
.soc-visit-stage::before{content:"";position:absolute;left:0;right:0;bottom:0;height:26%;background:linear-gradient(180deg,rgba(180,220,160,.35),rgba(150,205,140,.6));border-radius:0 0 18px 18px}
.soc-host{position:absolute;right:14%;bottom:14%;width:96px;height:96px}
.soc-guest{position:absolute;left:6%;bottom:10%;width:64px;height:64px;transform:translateX(-140%);opacity:0;transition:transform .8s var(--ease-spring),opacity .5s}
.soc-guest.arrived{transform:translateX(0);opacity:1}
.soc-guest-name{position:absolute;left:50%;top:-14px;transform:translateX(-50%);font-size:.58rem;background:#fff;border:1px solid var(--line);border-radius:999px;padding:.05rem .4rem;white-space:nowrap}
/* 首页称号小标 + 皇冠角标变体 */
.pet-t{font-style:normal;font-size:.5rem;background:linear-gradient(135deg,#FFE9A8,#FFC94D);color:#7A4E00;border-radius:999px;padding:.02rem .3rem;font-weight:800;vertical-align:1px}
.pet-badge.badge-crown{background:linear-gradient(135deg,#FFF3B0,#FFB347);box-shadow:0 0 0 2px rgba(255,210,90,.55),0 0 10px rgba(255,190,80,.7)}
@media(prefers-reduced-motion:reduce){.pet-body.act-roll,.pet-comp.act-roll,.pet-body.act-tail,.pet-comp.act-tail,.pet-body.act-heart,.pet-comp.act-heart,.pet-body.act-wave,.pet-comp.act-wave,
  .pet-body.act-sign,.pet-comp.act-sign,.pet-body.act-sleep,.pet-comp.act-sleep,.pet-stage.aura-glow .pet-comp::before,.pet-stage.aura-fire .pet-comp::before,.pet-stage.aura-gold .pet-comp::before,.pet-stage.glow-on::before,
  .pet-stage.lvfx3 .pet-comp,.pet-stage.evo-final .pet-comp,.pet-stage.skin-legend,.pet-pc,.pet-pcbg,.cel-big,.cel-card,#pet-celebrate .cf{animation:none!important}}
/* 美术升级 v3 §3.3：prefers-reduced-motion 补齐——呼吸位移（pet-breathe）、其余 5 个动作
   （眨眼/蹦跳/歪头/转圈/加倍蹦跳）、光效 ::after/::before 装饰、进化完全体脉冲，全部降级为静止。
   这些是 W1 新增/此前漏网的动效，减动偏好下一条都不该跑。 */
@media(prefers-reduced-motion:reduce){.pet-body.act-blink,.pet-comp.act-blink,.pet-comp.act-blink .pet-px,
  .pet-body.act-hop,.pet-comp.act-hop,.pet-body.act-wag,.pet-comp.act-wag,.pet-body.act-spin,.pet-comp.act-spin,
  .pet-body.act-double,.pet-comp.act-double,.pet-comp.act-heart::after,.pet-comp.act-sign::after,.pet-comp.act-sleep::after,
  .pet-stage.evo-final::after{animation:none!important}}
@media(prefers-reduced-motion:reduce){.soc-guest{transform:translateX(0);opacity:1}}
@media(prefers-reduced-motion:reduce){#pet-float{transition:none}}
/* ---------- v3.20.0 荣誉墙：星光卡 / 图鉴 / 学年视图 ---------- */
.hw-stars{display:flex;gap:.55rem;overflow-x:auto;padding:.2rem 0 .4rem;-webkit-overflow-scrolling:touch}
.hw-starcard{flex-shrink:0;width:104px;background:linear-gradient(160deg,#FFFDF5,#FFF7E0);border:1px solid #F3E3B3;
  border-radius:14px;padding:.6rem .5rem;text-align:center;cursor:pointer;box-shadow:var(--sh);
  transition:transform .2s var(--ease-spring)}
.hw-starcard:hover{transform:translateY(-3px) scale(1.03)}
.hw-starcard .sc-ic{display:block;font-size:1.5rem;margin-bottom:.2rem}
.hw-starcard b{display:block;font-size:.8rem;color:var(--ink)}
.hw-starcard .sc-t{display:block;font-size:.66rem;color:#8A5A00;margin-top:.15rem;line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hw-starcard .sc-d{display:block;font-size:.6rem;margin-top:.15rem}
.hw-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:.55rem}
.hw-type{border-radius:14px;padding:.7rem .3rem;font-weight:700;font-size:.8rem;cursor:pointer;text-align:center;
  transition:transform .15s var(--ease-spring);display:flex;flex-direction:column;align-items:center;gap:.25rem}
.hw-type span{font-size:1.5rem}
.hw-type small{font-weight:400;font-size:.58rem;opacity:.7}
.hw-type:active{transform:scale(.94)}
.hw-yearwall{display:flex;flex-wrap:wrap;gap:.4rem}
.hw-year-badge{display:inline-flex;align-items:center;gap:.3rem;border-radius:999px;padding:.32rem .7rem;
  font-size:.76rem;cursor:pointer;border:1px solid var(--line)}
.hw-year-badge b{font-weight:700}
.hw-year-badge i{font-style:normal;opacity:.55;font-size:.64rem;margin-left:.2rem}
/* 最近事件：纪念置顶金边 */
.rev-item.pinned{background:linear-gradient(90deg,#FFFBEB,transparent);border-radius:10px}
/* ---------- v3.23.0 荣誉墙：集体/个人分区 + 同类叠成的大卡 ---------- */
.hw-sec{margin-bottom:.9rem}
.hw-sec:last-child{margin-bottom:0}
.hw-sec-h{display:flex;align-items:center;gap:.45rem;font-weight:700;font-size:.95rem;margin-bottom:.5rem}
.hw-sec-n{margin-left:auto;font-weight:400;font-size:.72rem;color:var(--ink-3)}
.hw-cat-lg{display:flex;flex-direction:column;align-items:center;gap:.1rem;min-width:92px;
  border-radius:16px;padding:.6rem .5rem;cursor:pointer;transition:transform .15s var(--ease-spring);
  box-shadow:0 1px 6px rgba(30,40,80,.06)}
.hw-cat-lg:active{transform:scale(.95)}
.hw-cat-lg.on{box-shadow:0 0 0 2px var(--pri)}
.hw-cat-ic{font-size:1.45rem;line-height:1.1}
.hw-cat-n{font-size:.76rem;font-weight:700;max-width:96px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hw-cat-c{font-size:1.05rem;font-weight:700;line-height:1.15}
.hw-cat-m{font-style:normal;font-size:.6rem;font-weight:600;opacity:.75;margin-left:.15rem}

/* ---------- v3.20.1 移动端优化（手机端为主场景） ---------- */
.tab-mid .ic{font-size:1.5rem}
@media(max-width:640px){
  .hero{padding:1rem 1rem 1.1rem;border-radius:18px}
  .hero .hello{font-size:1.15rem}
  .poem{font-size:.76rem;margin:.3rem 0 .45rem}
  .pet{width:80px;top:6px;right:6px}
  .pet-body{width:64px;height:64px}
  .hero .hero-main{padding-right:84px}
  .pet-bubble{max-width:140px;font-size:.64rem;right:88px;top:10px}
  .cd-item{padding:.5rem .6rem}
  .cd-tx b{font-size:1.1rem}
  /* 触控目标 ≥40px */
  .alert-item .btn.sm,.sig .btn.sm{min-height:34px;padding:.4rem .7rem}
  .hw-starcard{width:96px}
  .hw-stars{scroll-snap-type:x mandatory}
  .hw-starcard{scroll-snap-align:start}
  .hw-grid{grid-template-columns:repeat(3,1fr)}
  /* 弹窗手机上限制高度、圆角统一，内容多时更好滚 */
  .modal{max-height:84vh}
  /* 底部安全区（iPhone 刘海屏手势条） */
  .tabbar{padding-bottom:calc(.3rem + env(safe-area-inset-bottom))}
  .sig-fold{padding:.6rem .8rem}
  .rev-item{padding:.35rem 0}
}

/* ═══════════ v3.21.0 移动端 UI 定稿（原型 v3 落地） ═══════════ */
/* 诗词单行（用户反馈：最好一行显示） */
.hero .poem{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:230px}
/* hero 不再放倒计时后，统计块回通栏 */
.hero{display:block}
.hero .stats{margin-top:.7rem}
.hero .stat b{font-variant-numeric:tabular-nums}
/* ── 今日要事合并卡（倒计时行 + 待办） ── */
.focuscard .cdrow{display:flex;align-items:center;gap:.7rem;padding:.55rem 0;border-bottom:1px solid var(--line);cursor:pointer}
.focuscard .cdrow:last-of-type{border-bottom:none}
.cdic{width:38px;height:38px;border-radius:12px;background:var(--bg);display:flex;align-items:center;justify-content:center;font-size:1.15rem;flex-shrink:0}
.cdic.add{color:var(--ink-3);font-weight:300;font-size:1.2rem}
.cdmid{flex:1;min-width:0}
.cdtt{font-size:.86rem;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cdtt.muted{font-weight:600}
.cddd{font-size:.68rem;color:var(--ink-3);margin-top:.05rem}
.cdnum{text-align:right;flex-shrink:0}
.cdnum b{font-size:1.25rem;font-weight:700;color:var(--pri);font-variant-numeric:tabular-nums;letter-spacing:-.02em;display:block;line-height:1.15}
.cdnum span{font-size:.6rem;color:var(--ink-3);font-weight:700}
.focuscard .cdrow.today{background:linear-gradient(90deg,#FFFBF0,transparent);border-radius:12px;margin:0 -.5rem;padding:.55rem .5rem}
.focuscard .cdrow.today .cdnum b{color:#D97706}
.focusdiv{display:flex;align-items:center;gap:.5rem;margin:.7rem 0 .15rem;font-size:.74rem;font-weight:700;color:var(--ink-2)}
.focusdiv::after{content:"";flex:1;height:1px;background:var(--line)}
.focusdiv .more{font-weight:700}
/* ── ⚡ 快捷底部抽屉宫格（替代扇形菜单） ── */
.quick-sheet-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:.85rem .3rem;padding:.3rem 0 .5rem}
.qs-item{border:none;background:none;cursor:pointer;text-align:center;font-size:.72rem;font-weight:700;color:var(--ink-2);display:flex;flex-direction:column;align-items:center;gap:.35rem;transition:transform .15s var(--ease-spring)}
.qs-item:active{transform:scale(.9)}
.qs-ic{width:50px;height:50px;border-radius:17px;background:var(--bg);display:flex;align-items:center;justify-content:center;font-size:1.45rem;box-shadow:var(--sh)}
/* ── 工具页用户卡 ── */
.ucard{display:flex;align-items:center;gap:.8rem;cursor:pointer}
.uav{width:48px;height:48px;border-radius:17px;background:var(--grad);display:flex;align-items:center;justify-content:center;color:#fff;font-size:1.25rem;font-weight:700;box-shadow:0 6px 16px rgba(79,124,255,.32);flex-shrink:0}
.pressable{transition:transform .15s var(--ease)}
.pressable:active{transform:scale(.97)}
/* ── 页面入场：卡片交错浮现（40ms，只动 transform/opacity） ── */
#page-body>*{animation:v321rise .24s var(--ease) both}
#page-body>*:nth-child(2){animation-delay:40ms}
#page-body>*:nth-child(3){animation-delay:80ms}
#page-body>*:nth-child(4){animation-delay:120ms}
#page-body>*:nth-child(5){animation-delay:150ms}
#page-body>*:nth-child(n+6){animation-delay:180ms}
@keyframes v321rise{from{opacity:0;transform:translateY(9px) scale(.995)}to{opacity:1;transform:none}}
/* ── 荣誉星光卡：金色流光扫过（纪念质感） ── */
.hw-starcard{position:relative;overflow:hidden}
.hw-starcard::after{content:"";position:absolute;top:-40%;left:-70%;width:45%;height:180%;background:linear-gradient(105deg,transparent,rgba(255,255,255,.7),transparent);transform:rotate(18deg);animation:hwshine 3.8s var(--ease) infinite}
.hw-starcard:nth-child(2)::after{animation-delay:.5s}
.hw-starcard:nth-child(3)::after{animation-delay:1s}
.hw-starcard:nth-child(4)::after{animation-delay:1.5s}
@keyframes hwshine{0%,55%{left:-70%}100%{left:150%}}
/* ── 底栏 FAB 按压反馈 + 荣誉墙页签 ── */
.tabbar button.tab-mid{transition:transform .15s var(--ease-spring)}
.tabbar button.tab-mid:active{transform:scale(.88) rotate(-4deg)}
/* 减弱动态：全部降级（保留透明度渐变） */
@media(prefers-reduced-motion:reduce){
  #page-body>*{animation:none!important}
  .hw-starcard::after{display:none}
  .qs-item,.pressable,.tabbar button.tab-mid{transition:none}
}

/* ═══════════ v3.26.0 移动端顶栏 + 录取对照双线 ═══════════ */
/* 顶栏：手机上一行塞了「标题 + 🔍 + N 个文字按钮」（荣誉墙 3 个、家长管理 4 个），
   #topbar-actions 带着 .row（会 wrap）→ 按钮在一个被压窄的盒子里竖堆 2–3 行，
   同时标题被压成 2 行（「荣誉墙」→「荣誉/墙」），粘性顶栏涨到 ~95px。
   修法：容器开 wrap、标题 nowrap+省略号；手机上动作区整体落到第二行、横向滑动。纯 CSS，17 个视图同时受益。 */
@media(max-width:640px){
  .topbar{padding:.8rem 1rem .5rem}
  #topbar-actions{flex:1 1 100%;order:10;flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;
    -webkit-overflow-scrolling:touch;scrollbar-width:none;gap:.4rem;
    margin:0 -1rem;padding:2px 1rem 4px}   /* 出血到屏幕边，滑动更自然 */
  #topbar-actions::-webkit-scrollbar{display:none}
  #topbar-actions>*{flex-shrink:0}         /* 关键：按钮不再被压窄、不折行 */
  #topbar-actions:empty{display:none}      /* 没有动作时不留空行 */
  #top-search{margin-right:0!important}
}
/* 录取对照双线：一个学生一块（原来是 N 列宽表，手机上得横向拖） */
.hs-row{padding:.5rem .15rem;border-bottom:1px solid var(--line)}
.hs-row:last-of-type{border-bottom:none}
.hs-est{font-size:var(--fs-lg);font-weight:700;color:var(--pri);font-variant-numeric:tabular-nums;letter-spacing:-.02em}
/* 体型不合身 / 未解锁：置灰但保留可见（藏起来玩家会以为没这件东西） */
.shop-item.nofit{opacity:.5;filter:saturate(.35)}
.shop-item.nofit::after{content:"体型不合身";position:absolute;right:6px;top:6px;font-size:.62rem;
  background:rgba(90,70,120,.85);color:#fff;border-radius:8px;padding:.1rem .35rem}
.shop-item.locked::after{content:"未解锁";right:6px;top:6px}
.pet-unlock{display:block;color:var(--pri,#6b4fd8);font-weight:600;margin-top:.15rem}

/* ═══════════ [G2 v3.35.0 惊喜收集] 相册 / 蛋窝 / 手工架 / 特权档 / 特效包 / 跟随 / 星座 ═══════════
   红线口径：以下全部是**表现层**——不新增经济、不改判定；天气/昼夜确定性；每包 kill-switch 关＝
   对应区块整卡消失（JS 不渲染），这里的类天然不出现。零新增图片素材（UI 蛋图已在 egg/ 目录）。 */

/* —— 🎖️ M5 特权档面板（只加不减：已到手永不追回；ladder 锁档展示诚实标价）—— */
.pet-priv .priv-rank{border:1px solid var(--line);border-radius:12px;padding:.35rem .6rem;margin-bottom:.4rem;background:#fff}
.pet-priv .priv-head{font-size:.78rem;font-weight:700;color:var(--muted)}
.pet-priv .priv-head.on{color:#7a5a10}
.pet-priv .alert-item{border:none;padding:.25rem 0}

/* —— 🥚 M6 蛋窝（孵化=累计 7 个照顾日；裂蛋 overlay 用 ui/egg 5 帧，进度换帧不换数）—— */
.egg-row{display:flex;gap:.6rem;align-items:center;border:1px solid var(--line);border-radius:14px;padding:.45rem .6rem;background:linear-gradient(160deg,#FBFAFF,#F4F1FA);margin-bottom:.45rem}
.egg-fig{position:relative;width:46px;height:46px;flex-shrink:0}
.egg-fig img{position:absolute;inset:0;width:100%;height:100%;image-rendering:pixelated}
.egg-fig .egg-crack{animation:egg-wiggle 3.4s var(--ease) infinite}
@keyframes egg-wiggle{0%,86%,100%{transform:rotate(0)}90%{transform:rotate(-3deg)}94%{transform:rotate(2.5deg)}}
.egg-tx{flex:1;min-width:0;font-size:.8rem}

/* —— 🧰 M6' 手工架（材料双货币终局水槽）—— */
.mat-bar{display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;font-size:.82rem;background:var(--pri-soft);border-radius:12px;padding:.4rem .7rem;margin-bottom:.5rem}
.shop-item.shelf .sic{font-size:1.5rem;line-height:1.6}

/* —— 📮 M4 班级旅程相册（邮戳二层册 + 收集度开门 + 概率公示）—— */
.pet-album-head{background:linear-gradient(165deg,#FBF7FF,#F3ECFA)}
.town-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:.45rem}
.town-cell{border:1px solid var(--line);border-radius:12px;padding:.4rem .55rem;background:#fff;text-align:center}
.town-cell.stamped{border-color:var(--green);background:linear-gradient(160deg,#F6FFEE,#EDFAE9)}
.town-cell b{font-size:.78rem;display:block}
.town-dots{display:flex;gap:4px;justify-content:center;margin:.25rem 0}
.town-dots i{width:14px;height:14px;border-radius:50%;background:var(--line)}
.town-dots i.on{background:linear-gradient(135deg,#FFD45E,#FF9F43)}
.pc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(128px,1fr));gap:.5rem}
.pc-tile{position:relative;border:2px solid #AEB6C2;border-radius:12px;overflow:hidden;background:#fff;padding:0;cursor:pointer;text-align:center;transition:transform .15s var(--ease-spring)}
.pc-tile:hover{transform:translateY(-2px) scale(1.02)}
.pc-tile img{width:100%;height:74px;object-fit:cover;display:block;border-bottom:1px solid var(--line)}
.pc-tile b{font-size:.74rem;display:block;margin-top:.25rem}
.pc-tile .small{font-size:.64rem}
.pc-tile .pc-open{position:absolute;right:4px;top:3px;font-style:normal;font-size:.7rem;background:rgba(255,255,255,.85);border-radius:8px;padding:0 3px}
.pc-tile.rar-白{border-color:#AEB6C2}.pc-tile.rar-青{border-color:#4FC3F7}.pc-tile.rar-绿{border-color:#34C77B}
.pc-tile.rar-赤{border-color:#FF6B6B;box-shadow:0 0 8px rgba(255,107,107,.25)}
.pc-tile.rar-金{border-color:#FFBE2E;box-shadow:0 0 10px rgba(255,190,46,.4)}
.pc-modal{position:fixed;inset:0;z-index:9994;display:flex;align-items:center;justify-content:center;background:rgba(30,26,16,.5);backdrop-filter:blur(2px);padding:1rem}
.pc-modal-card{background:#fff;border-radius:18px;padding:.8rem;max-width:430px;width:92%;box-shadow:0 18px 50px rgba(0,0,0,.3);text-align:center}
.pc-modal-card img{width:100%;border-radius:12px;image-rendering:auto}

/* —— 🧩 M8 套装光效（生效＝三件同穿；只加 box-shadow 表现，comp 的 filter 留给 lvfx 不抢）—— */
.pet-stage.set-mage{box-shadow:0 0 0 2px rgba(124,92,252,.35),0 0 16px rgba(124,92,252,.35)}
.pet-stage.set-samurai{box-shadow:0 0 0 2px rgba(255,190,46,.4),0 0 16px rgba(255,175,60,.4)}
.pet-stage.set-farm{box-shadow:0 0 0 2px rgba(63,164,91,.35),0 0 16px rgba(110,200,130,.35)}
.pet-stage.set-kitchen{box-shadow:0 0 0 2px rgba(232,69,95,.3),0 0 16px rgba(255,140,120,.35)}
.setcard{text-align:center}

/* —— ✨ M5 档4 主角常驻光效 + 档5 缎带角标（CSS 缎带零素材）—— */
.pet-stage.hero-glow{animation:hero-breath 4.2s var(--ease) infinite}
@keyframes hero-breath{0%,100%{box-shadow:0 0 0 1px rgba(255,201,77,.25),0 0 12px rgba(255,201,77,.25)}50%{box-shadow:0 0 0 3px rgba(255,201,77,.4),0 0 22px rgba(255,201,77,.45)}}
.pet-badge.badge-ribbon{background:linear-gradient(135deg,#FFE4EF,#FFC9DF);box-shadow:0 0 0 2px rgba(255,170,200,.6),0 0 10px rgba(255,140,180,.55)}
.pet-badge.badge-ribbon::after{content:"";position:absolute;left:6px;right:6px;bottom:-3px;height:5px;
  background:linear-gradient(90deg,transparent,#FF8FB8 20% 80%,transparent);border-radius:3px;clip-path:polygon(0 0,100% 0,88% 100%,50% 62%,12% 100%)}

/* —— 🐾 M5 跟随：路由级单例 overlay（默认关；解锁才可开；不遮操作）—— */
#pet-follow{position:fixed;right:10px;bottom:calc(64px + env(safe-area-inset-bottom));z-index:8500;
  display:flex;align-items:flex-end;gap:2px;animation:pf-in .5s var(--ease-spring)}
@keyframes pf-in{from{transform:translateY(16px) scale(.6);opacity:0}to{transform:none;opacity:1}}
#pet-follow .pf-body{width:56px;height:56px;border-radius:50%;background:radial-gradient(circle at 50% 62%,#FFF6D8,#FFE9AE);
  border:2px solid #fff;box-shadow:0 6px 16px rgba(90,70,10,.25);cursor:pointer;overflow:hidden;position:relative;transition:transform .15s var(--ease-spring)}
#pet-follow .pf-body:hover{transform:translateY(-2px) scale(1.05)}
#pet-follow .pf-body img{position:absolute;left:50%;bottom:2px;transform:translateX(-50%) scale(var(--pf-scale,1));width:44px;height:44px;object-fit:contain;image-rendering:pixelated}
#pet-follow .pf-name{position:absolute;left:50%;top:-1px;transform:translateX(-50%);font-size:.5rem;background:rgba(255,255,255,.9);border-radius:999px;padding:0 .3rem;white-space:nowrap;z-index:2}
#pet-follow.pf-big .pf-body{width:64px;height:64px;box-shadow:0 6px 18px rgba(90,70,10,.3),0 0 14px rgba(255,201,77,.5)}
#pet-follow .pf-x{border:none;background:rgba(60,50,20,.55);color:#fff;width:18px;height:18px;border-radius:50%;font-size:.72rem;line-height:1;cursor:pointer;padding:0;flex-shrink:0}

/* —— M16 特效包：天气氛围层（真 DOM 点阵，纯 CSS 零素材）+ 昼夜 stage 滤镜 —— */
.pet-stage .pet-wx{position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:140;display:none}
.pet-stage .pet-wx.w-snow{display:block;
  background-image:radial-gradient(2px 2px at 12% 18%,#fff,transparent 60%),radial-gradient(2px 2px at 42% 6%,#fff 55%,transparent 60%),
    radial-gradient(1.6px 1.6px at 68% 22%,#fff,transparent 60%),radial-gradient(2.2px 2.2px at 86% 10%,#F3F8FF,transparent 60%),
    radial-gradient(1.6px 1.6px at 26% 40%,#fff,transparent 60%),radial-gradient(2px 2px at 58% 48%,#F3F8FF,transparent 60%);
  background-size:100% 190%;animation:wx-fall 7s linear infinite;opacity:.85}
.pet-stage .pet-wx.w-petal{display:block;
  background-image:radial-gradient(2.6px 3.4px at 16% 12%,#FFC7DA,transparent 60%),radial-gradient(2.2px 3px at 55% 4%,#FFB3CC,transparent 60%),
    radial-gradient(2.6px 3.2px at 82% 24%,#FFD3E1,transparent 60%),radial-gradient(2px 2.8px at 34% 44%,#FFC7DA,transparent 60%);
  background-size:100% 200%;animation:wx-fall 9.5s linear infinite;opacity:.8}
.pet-stage .pet-wx.w-leaf{display:block;
  background-image:radial-gradient(2.6px 2px at 20% 10%,#E8A33D,transparent 60%),radial-gradient(2.2px 1.8px at 60% 22%,#D98B2E,transparent 60%),
    radial-gradient(2.8px 2.2px at 84% 6%,#F0B551,transparent 60%),radial-gradient(2px 1.8px at 40% 42%,#E8A33D,transparent 60%);
  background-size:100% 210%;animation:wx-fall 8.6s linear infinite;opacity:.8}
@keyframes wx-fall{from{background-position:0 -30%}to{background-position:0 70%}}
.pet-stage .pet-wx.w-wind{display:block;opacity:.5;
  background:repeating-linear-gradient(100deg,transparent 0 26px,rgba(200,225,255,.55) 26px 28px,transparent 28px 56px);
  background-size:220% 100%;animation:wx-blown 5s linear infinite}
@keyframes wx-blown{from{background-position:110% 0}to{background-position:-110% 0}}
.pet-stage .pet-wx.w-star{display:block;
  background-image:radial-gradient(1.6px 1.6px at 18% 16%,#FFF6C9,transparent 60%),radial-gradient(1.2px 1.2px at 46% 8%,#FFF,transparent 60%),
    radial-gradient(1.8px 1.8px at 72% 20%,#FFF6C9,transparent 60%),radial-gradient(1.2px 1.2px at 88% 34%,#FFF,transparent 60%),
    radial-gradient(1.4px 1.4px at 30% 30%,#FFF6C9,transparent 60%);
  animation:wx-tw 3.2s var(--ease) infinite}
@keyframes wx-tw{0%,100%{opacity:.55}50%{opacity:1}}
.pet-stage .pet-wx.w-sun{display:block;opacity:.55;
  background:linear-gradient(160deg,rgba(255,220,130,.5),rgba(255,240,180,0) 55%),
    repeating-linear-gradient(115deg,transparent 0 34px,rgba(255,230,150,.28) 34px 37px,transparent 37px 74px);
  animation:sun-drift 12s var(--ease) infinite alternate}
@keyframes sun-drift{from{opacity:.4}to{opacity:.75}}
.pet-stage .pet-wx.w-frost{display:block;opacity:.6;
  background:radial-gradient(circle at 50% 45%,transparent 58%,rgba(190,220,255,.5) 100%);
  box-shadow:inset 0 0 26px rgba(210,235,255,.75)}
/* 昼夜滤镜：只挪 stage 的 filter（comp 的 filter 留给 lvfx/套装，互不抢占） */
.pet-stage.wx-dawn{filter:brightness(1.03) saturate(1.08) hue-rotate(-6deg)}
.pet-stage.wx-day{filter:none}
.pet-stage.wx-dusk{filter:brightness(.98) saturate(1.12) sepia(.12)}
.pet-stage.wx-night{filter:brightness(.9) saturate(.82) hue-rotate(8deg)}
.wx-note{margin:.1rem 0 .5rem}

/* —— M16 破壳 reveal + 三阶进化仪式「升星感」—— */
.cel-hatch{display:flex;gap:.6rem;align-items:center;text-align:left}
.hatch-shell{position:relative;width:56px;height:56px;flex-shrink:0;animation:egg-wiggle 1.6s var(--ease) infinite}
.hatch-shell img{position:absolute;inset:0;width:100%;height:100%;image-rendering:pixelated}
.cel-evo{background:radial-gradient(circle at 50% 40%,rgba(64,52,120,.72),rgba(20,16,44,.82))}
.cel-evo .cel-card{background:linear-gradient(165deg,#1E1B33,#2C2650);border-color:#4C4280;color:#F5EFFF;
  box-shadow:0 18px 60px rgba(0,0,0,.55),0 0 40px rgba(255,201,77,.35)}
.cel-evo .cel-big.evo-big{font-size:3.4rem;animation:evo-rise 2.6s var(--ease-spring) infinite}
@keyframes evo-rise{0%,100%{transform:translateY(4px) scale(1);filter:drop-shadow(0 0 6px rgba(255,220,120,.7))}45%{transform:translateY(-14px) scale(1.25);filter:drop-shadow(0 0 18px rgba(255,235,160,1))}}
.cel-evo .evo-ring{position:absolute;left:50%;top:34%;width:190px;height:190px;margin:-95px 0 0 -95px;border-radius:50%;pointer-events:none;
  border:2px dashed rgba(255,214,120,.65);border-top-color:transparent;animation:evo-spin 3.4s linear infinite}
@keyframes evo-spin{to{transform:rotate(360deg)}}
.cel-evo .evo-title{color:#FFE49B;text-shadow:0 0 14px rgba(255,201,77,.6)}
.cel-evo .evo-stage{font-size:.85rem;color:#CFC3FF;margin-top:.2rem}
.cel-evo .evo-stage b{color:#FFE49B;font-size:1.05rem}
.cel-evo .cel-item{background:#282342;border-color:#473D78;color:#EFE8FF}
.cel-evo .cel-item span{color:#B9AEE0}

/* —— ㉑ 星座档（12 星连线路径＝表现艺术；点亮只增不减）—— */
.pet-astro .astro-wrap{display:flex;gap:1rem;align-items:center;flex-wrap:wrap}
.astro-svg{width:130px;height:136px;flex-shrink:0;background:linear-gradient(165deg,#232848,#141830);border-radius:14px}
.astro-svg circle{transition:r .3s}
.astro-svg circle.astro-on{filter:drop-shadow(0 0 4px rgba(255,212,94,.9));animation:astro-tw 2.8s var(--ease) infinite}
@keyframes astro-tw{0%,100%{opacity:.85}50%{opacity:1}}
.astro-steps{flex:1;min-width:180px;display:flex;flex-direction:column;gap:.3rem}
.astro-step{display:flex;gap:.5rem;align-items:baseline;font-size:.76rem;color:var(--muted);opacity:.55}
.astro-step.on{opacity:1;color:inherit}
.astro-step b{color:var(--pri)}
.astro-step.on b::after{content:" ✓"}

/* —— ⑯ 成就三阶框（bronze/silver/gold 边框递进；图鉴框随成就解锁出现）—— */
.ach-item.frame-bronze{border-color:#B87333;box-shadow:inset 0 0 0 1px rgba(184,115,51,.35)}
.ach-item.frame-silver{border-color:#A9B4C2;box-shadow:inset 0 0 0 1px rgba(170,180,195,.5),0 0 8px rgba(190,205,225,.35)}
.ach-item.frame-gold{border-color:#E7B94A;background:linear-gradient(160deg,#FFFCEC,#FFF6D8);box-shadow:inset 0 0 0 1px rgba(231,185,74,.55),0 0 12px rgba(255,201,77,.4)}

/* —— 减弱动态：G2 新动效全部降级为静止（透明度渐变保留）—— */
@media(prefers-reduced-motion:reduce){
  .egg-fig .egg-crack,.hatch-shell{animation:none!important}
  .pet-stage.hero-glow{animation:none;box-shadow:0 0 0 2px rgba(255,201,77,.3)}
  .pet-stage .pet-wx.w-snow,.pet-stage .pet-wx.w-petal,.pet-stage .pet-wx.w-leaf{animation:none!important;background-position:0 8%}
  .pet-stage .pet-wx.w-wind,.pet-stage .pet-wx.w-star,.pet-stage .pet-wx.w-sun{animation:none!important}
  #pet-follow{animation:none!important}
  .cel-evo .cel-big.evo-big,.cel-evo .evo-ring{animation:none!important}
  .astro-svg circle.astro-on{animation:none!important;opacity:1}
  .pc-tile:hover{transform:none}
}
/* 打印/导出物上不留跟随小宠物和天气层 */
@media print{#pet-follow,.pet-wx{display:none!important}}

/* ═══════════ [G3 v3.36.0 运营与羁绊] 技能树 / 赛季集章册 / 全校大花 / 性格灵魂 / 搭子 / 巅峰 / 三选二 ═══════════
   红线口径同 G2：以下全是**表现层**。技能树节点只切开关（无产出）、大花只画匿名聚合进度条、
   搭子只画收藏物轨、巅峰只画称号点——每包 kill-switch 关＝JS 不渲染该区块，这里的类自然不出现。
   零新增图片素材（图标全部走 emoji/字符），故镜像增量只有本文件与 JS 分片的字节。 */

/* —— 🛡️ M7 守护技能树：三系 × 四层；点了实心、可点描边、前置灰 —— */
.g3-skill .g3-skill-note{margin:.2rem 0 .6rem}
.g3-branch{margin-bottom:.7rem}
.g3-branch-hd{font-size:.82rem;font-weight:700;color:var(--muted);margin-bottom:.3rem}
.g3-nodes{display:grid;grid-template-columns:repeat(auto-fill,minmax(148px,1fr));gap:.4rem}
.g3-node{position:relative;display:flex;flex-direction:column;gap:.15rem;text-align:left;align-items:flex-start;
  border:1px solid var(--line);border-radius:14px;padding:.5rem .55rem;background:#fff;cursor:pointer;
  font:inherit;font-size:.76rem;line-height:1.35;transition:transform .16s var(--ease),box-shadow .16s var(--ease)}
.g3-node:hover{transform:translateY(-1px);box-shadow:0 6px 16px rgba(60,40,90,.09)}
.g3-node.on{border-color:#7a5a10;background:linear-gradient(160deg,#FFFCEC,#FFF4D6);box-shadow:inset 0 0 0 1px rgba(231,185,74,.45)}
.g3-node.lock{opacity:.5;cursor:not-allowed}
.g3-node-t{position:absolute;top:.35rem;right:.45rem;font-size:.62rem;color:var(--muted);font-weight:700}
.g3-node-ic{font-size:1.05rem}
.g3-node-nm{font-weight:700}
.g3-node-ds{color:var(--muted);font-size:.7rem}
.g3-node-mx,.g3-node-req{color:#a3543f;font-size:.66rem}
.g3-skill-foot{justify-content:space-between;align-items:center;margin-top:.2rem}
/* —— 📅 M9 赛季事件 + 集章册 + 🌻 全校大花 —— */
.g3-evs{display:flex;flex-direction:column;gap:.3rem;margin:.35rem 0 .5rem}
.g3-ev{display:flex;align-items:center;gap:.45rem;border:1px solid var(--line);border-radius:12px;padding:.4rem .55rem;font-size:.78rem}
.g3-ev.st-got{border-color:#3f9d6b;background:linear-gradient(160deg,#F3FBF6,#EAF7EF)}
/* 五态与后端 _season_view 的 state 一字对齐（got/open/soon/next/catchup）——
   早先写的 st-miss/st-past 是后端从未产出的名字，样式挂空＝红线里「错过」被画成红色羞耻，删掉。 */
.g3-ev.st-open{border-color:#5a7fb8;background:linear-gradient(160deg,#F4F8FD,#EDF3FB)}
.g3-ev.st-catchup{border-color:#c9789b;background:#FDF4F8}
.g3-ev.st-soon,.g3-ev.st-next{opacity:.72}
.g3-ev-ic{font-size:1.05rem;flex-shrink:0}
.g3-ev-tx{flex:1;min-width:0}
.g3-book-row{display:flex;flex-wrap:wrap;gap:.3rem;margin:.3rem 0}
.g3-mark{border:1px dashed var(--line);border-radius:999px;padding:.2rem .5rem;font-size:.72rem;color:var(--muted);opacity:.62}
.g3-mark.got{border-style:solid;opacity:1;color:var(--ink);background:#F6F3FB}
.g3-mark.lim.got{background:linear-gradient(160deg,#FFFCEC,#FFF4D6);border-color:#7a5a10}
.g3-bar{height:12px;border-radius:999px;background:#EFEAF6;overflow:hidden;margin:.35rem 0}
.g3-bar i{display:block;height:100%;background:linear-gradient(90deg,#7FC98B,#E7B94A);border-radius:999px;transition:width .5s var(--ease)}
.g3-flower-meta,.g3-flower-act{margin-top:.25rem}
.g3-flower-act{flex-wrap:wrap;gap:.35rem}
/* —— 🫧 M14 性格种子 / 气泡 / 灵魂日记 —— */
.g3-dims{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:.25rem .6rem;margin:.3rem 0}
.g3-dim{display:flex;align-items:center;gap:.35rem;font-size:.72rem}
.g3-dim-bar{flex:1;height:7px;border-radius:999px;background:#EFEAF6;overflow:hidden;display:block}
.g3-dim-bar b{display:block;height:100%;background:var(--pri);opacity:.75;border-radius:999px}
.g3-bubbles{display:flex;flex-wrap:wrap;gap:.3rem;margin:.4rem 0 .2rem}
.g3-bub{border:1px solid var(--line);border-radius:999px;padding:.22rem .55rem;font-size:.72rem;background:#FBFAFF}
.g3-soul-act{flex-wrap:wrap;gap:.4rem;align-items:center;margin-top:.35rem}
.g3-diaries{display:flex;flex-direction:column;gap:.5rem;max-height:56vh;overflow:auto}
.g3-diary{border:1px solid var(--line);border-radius:14px;padding:.5rem .6rem;background:#FBFAFF}
.g3-diary-d{font-size:.7rem;color:var(--muted);margin-bottom:.2rem}
.g3-diary-t{font-size:.86rem;line-height:1.5}
/* —— 🫱 M15 搭子火花（收藏物轨 + 双向冷静 + 单方解绑） —— */
.g3-buddy.st-active{border-color:#3f9d6b}
.g3-buddy.st-cooling,.g3-buddy.st-pending{border-color:#d6b25c}
.g3-buddy-in,.g3-buddy-wait,.g3-buddy-cool,.g3-buddy-on,.g3-buddy-end{display:flex;flex-wrap:wrap;align-items:center;gap:.4rem;
  border:1px solid var(--line);border-radius:12px;padding:.45rem .55rem;margin:.35rem 0;font-size:.78rem}
.g3-buddy-on{background:linear-gradient(160deg,#F3FBF6,#EAF7EF);border-color:#3f9d6b;flex-direction:column;align-items:flex-start}
.g3-buddy-cool{background:#FFFBF1}
.g3-buddy-act{gap:.4rem;flex-wrap:wrap}
.g3-buddy-cand{display:flex;flex-wrap:wrap;gap:.35rem;margin-top:.35rem}
.g3-thanks{background:#F6F3FB}
.g3-solo{border-top:1px dashed var(--line);margin-top:.5rem;padding-top:.4rem;font-size:.78rem}
/* —— ⛰️ 巅峰火花：只画 12 个点，不画任何数值条 —— */
.g3-peak-row{display:flex;flex-wrap:wrap;gap:.25rem;margin:.35rem 0}
.g3-peak-dot{width:1.5rem;height:1.5rem;border-radius:50%;border:1px solid var(--line);display:flex;align-items:center;
  justify-content:center;font-size:.62rem;color:var(--muted)}
.g3-peak-dot.on{border-color:#E7B94A;background:linear-gradient(160deg,#FFFCEC,#FFE9A8);color:#7a5a10;font-weight:700}
/* —— 🪙 三选二余额去向 —— */
.g3-sink-block{border:1px solid var(--line);border-radius:12px;padding:.45rem .55rem;margin:.4rem 0}
.g3-lux{display:flex;flex-wrap:wrap;gap:.35rem;margin-top:.35rem}
.g3-sink-off{margin-top:.35rem;color:#a3543f}
/* —— 我的宠物页的一行摘要 —— */
.g3-mini{display:flex;flex-wrap:wrap;gap:.35rem;align-items:center;font-size:.75rem}
.g3-minilink{color:var(--pri);cursor:pointer;font-weight:700}
.g3-foot{font-size:.72rem}
/* 减弱动态：G3 没有任何循环动效，进度条/卡片位移一并降级为静止 */
@media(prefers-reduced-motion:reduce){
  .g3-node:hover{transform:none;box-shadow:none}
  .g3-bar i{transition:none}
}
@media print{.g3-skill,.g3-buddy,.g3-sink,.g3-mini{display:none!important}}
