/* ============================================================
   佑佑 任务岛 - 样式表
   孩子端明亮卡通 / 家长端清爽列表 / 全套捕捉进化动画
   ============================================================ */

:root {
  --yellow: #ffd54f;
  --red: #ee4444;
  --blue: #4fc3f7;
  --green: #66bb6a;
  --bg-top: #6ec6ff;
  --bg-bottom: #b3e5fc;
  --card: #ffffff;
  --ink: #263238;
  --ink-soft: #607d8b;
  --radius: 20px;
  --shadow: 0 6px 20px rgba(38, 50, 56, .15);
}

* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body { height: 100%; }

body {
  font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif;
  color: var(--ink);
  background: linear-gradient(180deg, var(--bg-top), var(--bg-bottom)) fixed;
  overscroll-behavior: none;
}

.hidden { display: none !important; }

/* ---------- 加载屏 ---------- */
.loading-screen {
  min-height: 100vh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 20px; color: #fff;
}
.loading-ball {
  width: 64px; height: 64px; border-radius: 50%;
  background: linear-gradient(#e53935 50%, #fff 50%);
  border: 4px solid #263238; position: relative;
  animation: ball-bounce 0.7s ease-in-out infinite alternate;
}
.loading-ball::before {
  content: ''; position: absolute; top: 50%; left: -4px; right: -4px; height: 8px;
  transform: translateY(-50%); background: #263238;
}
.loading-ball::after {
  content: ''; position: absolute; top: 50%; left: 50%; width: 20px; height: 20px;
  border-radius: 50%; transform: translate(-50%, -50%);
  background: #fff; border: 4px solid #263238;
}
@keyframes ball-bounce { from { transform: translateY(0) rotate(0); } to { transform: translateY(-18px) rotate(20deg); } }

/* ---------- 顶部栏 ---------- */
.topbar {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px;
  background: rgba(255, 255, 255, .85); backdrop-filter: blur(10px);
  box-shadow: 0 2px 12px rgba(38, 50, 56, .12);
}
.topbar .title { font-size: 20px; font-weight: 800; }
.topbar .title small { display: block; font-size: 11px; font-weight: 400; color: var(--ink-soft); }

.badges { display: flex; gap: 8px; }
.badge {
  display: flex; align-items: center; gap: 4px;
  padding: 6px 12px; border-radius: 999px; font-weight: 800; font-size: 15px;
  background: #fff7dd; color: #b8860b; box-shadow: var(--shadow);
}
.badge.ball { background: #ffe8e8; color: var(--red); }
.badge.shake-it { animation: pop .4s ease; }
@keyframes pop { 50% { transform: scale(1.35); } }

/* ---------- 内容区 ---------- */
.page { padding: 16px 16px calc(120px + env(safe-area-inset-bottom)); max-width: 720px; margin: 0 auto; }

/* 进度卡 */
.progress-card {
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 16px; margin-bottom: 16px;
  display: flex; flex-direction: column; gap: 14px;   /* 每组进度条之间留足间距，避免必做/选做贴在一起 */
}
/* 每一组「标题 + 进度条」独立成块 */
.progress-item { display: flex; flex-direction: column; }
.progress-item + .progress-item {
  border-top: 1px dashed rgba(0, 0, 0, .07);   /* 多组之间再加一条分隔线，视觉上不粘连 */
  padding-top: 12px;
}
.progress-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; column-gap: 12px; row-gap: 4px; margin-bottom: 10px; }
.progress-head b { font-size: 18px; line-height: 1.35; }
.progress-head span { color: var(--ink-soft); font-size: 13px; text-align: right; flex: 0 1 auto; }
.progress-track { height: 16px; background: #eceff1; border-radius: 999px; overflow: hidden; }
.progress-fill {
  position: relative; height: 100%; border-radius: 999px; overflow: hidden;
  transition: width .5s ease, background .45s ease;
  background: linear-gradient(90deg, #c3d7ef, #acc9ea);   /* 兜底=淡蓝，正常情况下 JS 按百分比写内联色 */
}
/* 完成：绿色底 + 一道白光扫过（原来的黄色闪烁容易被当成「警告」，也不如绿色直观） */
.progress-fill.full {
  background: linear-gradient(90deg, #43a047, #66bb6a);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .35);
}
.progress-fill.full::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, .68) 50%, transparent 70%);
  transform: translateX(-120%);
  animation: pf-sheen 1.9s ease-in-out infinite;
}
@keyframes pf-sheen {
  0%        { transform: translateX(-120%); }
  55%, 100% { transform: translateX(120%); }
}
/* 必做/选做进度条可点击 → 弹出任务清单 */
.progress-item.clickable { cursor: pointer; user-select: none; -webkit-tap-highlight-color: transparent; transition: transform .12s; }
.progress-item.clickable:active { transform: scale(.985); }
.pd-tap { margin-top: 6px; text-align: right; font-size: 11px; color: #b0bec5; letter-spacing: .3px; }
.progress-item.clickable:active .pd-tap { color: var(--blue); }

/* ---------- 任务卡片 ---------- */
.task-card {
  display: flex; align-items: center; gap: 12px;
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 14px 16px; margin-bottom: 12px;
  transition: transform .15s ease, opacity .3s;
}
.task-card:active { transform: scale(.98); }
.task-card .emoji {
  width: 48px; height: 48px; flex: none; display: grid; place-items: center;
  font-size: 26px; background: #f1f8ff; border-radius: 14px;
}
.task-card .info { flex: 1; min-width: 0; }
.task-card .info b { display: block; font-size: 17px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.task-card .info span { font-size: 12px; color: var(--ink-soft); }
.task-card .pts { font-weight: 800; color: #f57f17; font-size: 15px; flex: none; }

.btn-done {
  flex: none; border: 0; cursor: pointer;
  padding: 12px 20px; border-radius: 999px;
  font-size: 16px; font-weight: 800; color: #fff;
  background: linear-gradient(135deg, #42a5f5, #1e88e5);
  box-shadow: 0 4px 0 #1565c0; transition: transform .1s;
}
.btn-done:active { transform: translateY(3px); box-shadow: none; }
.task-card.done { opacity: .65; }
.task-card.done .emoji { background: #e8f5e9; }
.task-card.done .btn-done {
  background: linear-gradient(135deg, #66bb6a, #43a047); box-shadow: 0 4px 0 #2e7d32;
}
/* 已提交（待家长审批）态：按下观感，卡片保持原位 */
.task-card.submitted { opacity: .9; border-color: #c5cae9; }
.task-card.submitted .emoji { background: #e8eaf6; }
.task-card.submitted .btn-done.submitted-btn {
  background: linear-gradient(135deg, #5c6bc0, #3949ab);
  box-shadow: 0 2px 0 #283593;
  transform: translateY(2px);
}
.task-card.just-done { animation: done-jump .5s ease; }
@keyframes done-jump { 30% { transform: translateY(-8px) scale(1.03); } }

/* ---------- 底部导航 ---------- */
.tabbar {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 50;
  display: flex; justify-content: space-around;
  background: rgba(255, 255, 255, .92); backdrop-filter: blur(10px);
  border-top: 1px solid #e0e0e0; padding: 6px 0 max(6px, env(safe-area-inset-bottom));
}
.tabbar button {
  border: 0; background: none; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  font-size: 11px; color: var(--ink-soft); padding: 6px 14px; border-radius: 14px;
}
.tabbar button .ico { font-size: 24px; line-height: 1; }
.tabbar button.on { color: var(--red); background: #fff3f3; font-weight: 700; }
.tabbar button.secret { opacity: .25; }
/* 悬浮贴边操作按钮（右下角，返回/登出） */
.fab-col {
  position: fixed; bottom: 24px; right: 12px; z-index: 60;
  display: flex; flex-direction: column; gap: 8px;
}
/* 孩子端"登出"悬浮按钮：移到 tabbar 上方，避免遮挡"家长"入口；并支持拖动 */
#kid-logout-fab {
  bottom: calc(80px + env(safe-area-inset-bottom));
  cursor: grab; touch-action: none;
}
#kid-logout-fab:active { cursor: grabbing; }
.fab-btn {
  border: 0; cursor: pointer; font-size: 12px; font-weight: 600;
  padding: 9px 14px; border-radius: 999px;
  background: rgba(255, 255, 255, .96); color: var(--ink);
  box-shadow: 0 4px 14px rgba(31, 64, 98, .22); border: 1px solid #eee;
}
.fab-btn:active { transform: scale(.96); }
.fab-btn.logout { color: #e53935; }

/* ---------- 宝可梦页 ---------- */
.section-title { margin: 18px 4px 10px; font-size: 16px; font-weight: 800; display: flex; justify-content: space-between; align-items: center; }
.section-title small { color: var(--ink-soft); font-weight: 400; }

.pm-card {
  display: flex; gap: 12px; align-items: center;
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 12px 14px; margin-bottom: 12px; position: relative; overflow: hidden;
}
.pm-card.shiny { background: linear-gradient(135deg, #fffde7, #fff8e1); }
.pm-card img { width: 72px; height: 72px; image-rendering: pixelated; flex: none; }
.pm-card .pm-info { flex: 1; min-width: 0; }
.pm-card .pm-name { font-weight: 800; font-size: 17px; }
.pm-card .pm-lv { font-size: 12px; color: var(--ink-soft); margin: 2px 0 6px; }
.exp-track { height: 10px; background: #eceff1; border-radius: 999px; overflow: hidden; }
.exp-fill {
  height: 100%; border-radius: 999px; transition: width .6s ease;
  background: linear-gradient(90deg, #7e57c2, #b39ddb);
}
.pm-actions { display: flex; flex-direction: column; gap: 6px; flex: none; }
.pm-actions button {
  border: 0; cursor: pointer; border-radius: 999px; padding: 7px 12px;
  font-size: 12px; font-weight: 800; color: #fff;
}
.btn-feed { background: linear-gradient(135deg, #7e57c2, #5e35b1); box-shadow: 0 3px 0 #4527a0; }
.btn-evo { background: linear-gradient(135deg, #ffb300, #fb8c00); box-shadow: 0 3px 0 #e65100; }
.btn-evo:disabled { filter: grayscale(1); opacity: .5; box-shadow: none; }
.btn-lead { background: linear-gradient(135deg, #ef5350, #e53935); box-shadow: 0 3px 0 #b71c1c; }
.lead-star { position: absolute; top: 8px; right: 10px; font-size: 18px; }

/* 捕捉区：顶部只留一行球数 + 两个并排按钮，规则说明收到折叠小抄里 */
.catch-zone {
  background: linear-gradient(135deg, #ffe0b2, #ffcc80);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 12px 14px 14px; margin-bottom: 4px; text-align: center;
}
.catch-zone .ball-row { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 0 0 10px; min-height: 24px; flex-wrap: wrap; }
.catch-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.ball-count { font-size: 12px; color: #8d6e63; font-weight: 700; white-space: nowrap; }
.ball-count b { font-size: 14px; color: #5d4037; }
.ball-icons { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.ball-more { font-size: 11px; color: #8d6e63; font-weight: 800; }
.ball-empty { font-size: 12px; color: #8d6e63; }
.mini-ball {
  width: 18px; height: 18px; border-radius: 50%; position: relative;
  background: linear-gradient(#e53935 50%, #fff 50%); border: 2px solid #263238;
}
.mini-ball::before { content: ''; position: absolute; top: 50%; left: -2px; right: -2px; height: 2px; transform: translateY(-50%); background: #263238; }
.mini-ball::after { content: ''; position: absolute; top: 50%; left: 50%; width: 6px; height: 6px; border-radius: 50%; transform: translate(-50%, -50%); background: #fff; border: 1.5px solid #263238; }

.btn-big {
  border: 0; cursor: pointer; width: 100%;
  display: flex; align-items: center; justify-content: center; gap: 5px;
  padding: 13px 6px; border-radius: 999px;
  font-size: 17px; font-weight: 800; color: #fff; white-space: nowrap;
  background: linear-gradient(135deg, #ef5350, #e53935);
  box-shadow: 0 5px 0 #b71c1c;
}
.btn-big small { font-size: 12px; font-weight: 800; opacity: .9; }
.btn-big:active { transform: translateY(4px); box-shadow: none; }
.btn-big.buy { background: linear-gradient(135deg, #ffd54f, #ffb300); color: #6d4c00; box-shadow: 0 5px 0 #b8860b; }
.btn-big:disabled { filter: grayscale(1); opacity: .55; box-shadow: none; }
/* 窄屏：两个按钮并排也不能让文字挤成两行 */
@media (max-width: 360px) {
  .catch-actions { gap: 8px; }
  .btn-big { font-size: 15px; padding: 12px 4px; gap: 4px; }
  .btn-big small { font-size: 11px; }
  .catch-actions .btn-big svg { width: 18px; height: 18px; }
}

/* 图鉴 */
.dex-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: 8px; }
.dex-cell {
  background: var(--card); border-radius: 14px; box-shadow: var(--shadow);
  aspect-ratio: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; position: relative; overflow: hidden;
  cursor: pointer; transition: transform .12s;
}
.dex-cell:active { transform: scale(.94); }
.dex-cell.unknown { cursor: pointer; }
.dex-cell.unknown:active { transform: scale(.94); }
.dex-cell img { width: 46px; height: 46px; image-rendering: pixelated; }
.dex-cell .no { font-size: 9px; color: var(--ink-soft); position: absolute; top: 3px; left: 6px; }
.dex-cell.unknown img { filter: brightness(0) opacity(.6); }
.dex-cell.unknown .q { position: absolute; font-size: 20px; font-weight: 900; color: #90a4ae; }
.dex-cell .star { position: absolute; top: 2px; right: 4px; font-size: 12px; }
.dex-cell.shiny-cell { background: linear-gradient(135deg, #fffde7, #ffecb3); }
.dex-cell.got-new { animation: pop .5s ease; }
.sparkle {
  position: absolute; font-size: 14px; pointer-events: none;
  animation: sparkle-fly 1.2s ease-out forwards;
}
@keyframes sparkle-fly {
  0% { transform: translateY(6px) scale(.4); opacity: 0; }
  30% { opacity: 1; }
  100% { transform: translateY(-26px) scale(1.1) rotate(40deg); opacity: 0; }
}

/* ---------- 我的页 ---------- */
.stat-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px; }
.stat-card {
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 16px; text-align: center;
}
.stat-card b { display: block; font-size: 28px; color: #e53935; }
.stat-card span { font-size: 12px; color: var(--ink-soft); }

/* 「我的」页顶部：4 个数字卡片 + 右下角快捷操作（成就图这类"偶尔用一次"的入口，别做成整块大按钮） */
.me-head { margin-bottom: 4px; }
.me-actions { display: flex; justify-content: flex-end; margin: -6px 4px 0; }
.me-actions .btn-ghost.mini { padding: 6px 14px; font-size: 12px; }
/* 积分记录筛选（全部 / 获得 / 扣分） */
.log-filter { display: flex; gap: 6px; margin: 0 4px 8px; }
.log-tab {
  border: 1.5px solid #e3e8ef; background: #fff; border-radius: 999px;
  padding: 5px 14px; font-size: 12px; font-weight: 700; color: var(--ink-soft); cursor: pointer;
}
.log-tab.on { border-color: var(--blue); background: #e8f6fe; color: #0277bd; }

/* 「我的」页各明细列表：超过一定条数后固定高度、列表内部滚动，别把页面越拉越长 */
.log-list {
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  max-height: 340px; overflow-y: auto; overflow-x: hidden;
  -webkit-overflow-scrolling: touch; scrollbar-width: thin;
}
.log-item { display: flex; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid #f5f5f5; font-size: 14px; }
.log-item:last-child { border-bottom: 0; }
.log-item .when { color: var(--ink-soft); font-size: 12px; }
.log-item .amt { font-weight: 800; }
.amt.plus { color: #43a047; }
.amt.minus { color: #e53935; }

/* ---------- 家长端 ---------- */
.parent-head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 16px;
}
.parent-head h2 { font-size: 20px; }
.btn-ghost {
  border: 1px solid #b0bec5; background: #fff; color: var(--ink-soft);
  border-radius: 999px; padding: 8px 16px; font-size: 13px; cursor: pointer;
}

.panel {
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 16px; margin-bottom: 16px;
}
.panel h3 { font-size: 14px; margin: 12px 0 8px; display: flex; justify-content: space-between; align-items: center; }

.tpl-row { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  border: 1px solid #90caf9; background: #e3f2fd; color: #1565c0;
  border-radius: 999px; padding: 8px 14px; font-size: 13px; cursor: pointer; font-weight: 700;
}
.chip.red { border-color: #ef9a9a; background: #ffebee; color: #c62828; }
/* 家长端「管理历史类别」：一行一个小胶囊，名称不换行，图标缩到 15px 免得把行撑高 */
.cat-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.cat-tag {
  display: inline-flex; align-items: center; gap: 5px; max-width: 100%;
  padding: 4px 5px 4px 9px; background: #e3f2fd; border: 1px solid #bbdefb;
  border-radius: 999px; font-size: 13px; font-weight: 700; color: #1565c0;
  line-height: 1.5; white-space: nowrap;
}
.cat-tag-ico { display: inline-flex; flex: 0 0 auto; align-items: center; justify-content: center; width: 15px; height: 15px; }
.cat-tag-ico svg, .cat-tag-ico img { display: block; width: 15px; height: 15px; }
.cat-tag-name { flex: 0 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.cat-tag-x {
  display: inline-flex; flex: 0 0 auto; align-items: center; justify-content: center;
  width: 19px; height: 19px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(239, 83, 80, .13); color: #e53935;
  font-size: 11px; line-height: 1; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.cat-tag-x:active { background: rgba(239, 83, 80, .28); }
.cat-add { display: inline-flex; align-items: center; gap: 6px; }
.cat-add-inp {
  width: 104px; padding: 6px 12px; font-size: 13px;
  border: 1px solid #e0e0e0; border-radius: 999px; font-family: inherit;
}
.cat-add-inp:focus { outline: none; border-color: var(--blue); }
.cat-add .chip { padding: 6px 14px; font-size: 13px; }
/* 常用任务标签：图标 + 名称 + 分数 + ✕；单击=添加任务，长按=编辑标签（见 bindQuickLongPress） */
.quick-chip {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition: transform .12s ease, box-shadow .12s ease;
}
/* 手机长按不能选中文字/弹复制菜单，否则会打断长按手势 */
.quick-chip, .quick-chip * {
  -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
/* 家长端任务行长按拖动排序同理：禁止选中文字/弹复制菜单，否则系统选字会抢走长按 */
.prow, .prow * {
  -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
/* 图标/文字不接收指针事件：长按的落点变成标签本身，系统就不会当作文本去选字（✕ 仍可点） */
.quick-chip svg, .quick-chip .qc-name, .quick-chip .qc-pts { pointer-events: none; }
.quick-chip .qc-name { max-width: 10em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.quick-chip .qc-pts { color: #ef6c00; font-size: 12px; }
.quick-chip .qc-x {
  color: #c62828; padding: 0 4px; border-radius: 50%; font-weight: 400; line-height: 1.1;
}
.quick-chip.pressed { transform: scale(.95); box-shadow: 0 0 0 2px rgba(21, 101, 192, .35) inset; }
/* 拖动中的标签：放大 + 蓝边 + 轻微上浮，iOS 不支持 vibrate，靠这个视觉反馈提示"已可拖" */
.quick-chip.dragging {
  transform: scale(1.06);
  box-shadow: 0 6px 16px rgba(21, 101, 192, .25), 0 0 0 2px rgba(21, 101, 192, .55) inset;
  z-index: 3; position: relative;
}
.quick-add { flex: 0 0 auto; padding: 6px 14px; font-size: 18px; line-height: 1.35; }
/* 常用任务标题行：标题不换行，「排序」「＋」固定在右边；窄屏藏掉说明文字免得挤成两行 */
.quick-head h3 { white-space: nowrap; }
.quick-head h3 small { display: inline-block; max-width: 12em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
@media (max-width: 370px) { .quick-head h3 small { display: none; } }
/* 常用任务「排序」按钮：普通态淡蓝，排序中变绿色「确认」 */
.quick-sort { flex: 0 0 auto; padding: 6px 12px; font-size: 13px; line-height: 1.35; }
.quick-sort.active { border-color: #66bb6a; background: #e8f5e9; color: #2e7d32; }
/* 排序模式：标签变虚线；✕ 只是隐藏但保留占位，标签宽度不变，否则一进排序每行能多挤下一个、布局乱跳 */
#pt-quick-list.sorting .quick-chip {
  border-style: dashed; cursor: grab;
  /* 手机上必须关掉浏览器的滚动/缩放接管，否则长按拖动会被「页面滚动」抢先 */
  touch-action: none; -webkit-user-drag: none;
}
#pt-quick-list.sorting .quick-chip .qc-x { visibility: hidden; pointer-events: none; }
/* 手机端常用任务固定两列网格：标签名字长短不会再让每行个数乱跳，普通/排序两种状态布局完全一致 */
@media (max-width: 520px) {
  #pt-quick-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; align-items: stretch; }
  #pt-quick-list .quick-chip { width: auto; max-width: none; min-width: 0; overflow: hidden; }
  #pt-quick-list .quick-chip .qc-name { flex: 1 1 auto; min-width: 0; max-width: none; }
  #pt-quick-list .quick-chip .qc-pts, #pt-quick-list .quick-chip .qc-x { flex: 0 0 auto; }
}
/* 更窄（≤400）：两列偏挤，收紧内边距/✕，名字多露 1~2 个字 */
@media (max-width: 400px) {
  #pt-quick-list .quick-chip { padding: 7px 10px; gap: 4px; }
  #pt-quick-list .quick-chip .qc-pts { font-size: 11px; }
  #pt-quick-list .quick-chip .qc-x { padding: 0 1px; }
}
/* 320 档：两列太挤，藏掉分数，保证名字还能看到 4~5 个字 */
@media (max-width: 360px) {
  #pt-quick-list { gap: 6px; }
  #pt-quick-list .quick-chip { padding: 7px 9px; font-size: 12px; }
  #pt-quick-list .quick-chip .qc-pts { display: none; }
}
/* 拖动中的标签：让出指针事件，否则 elementFromPoint 永远只命中它自己 */
.quick-chip.dragging {
  pointer-events: none; transform: scale(1.06);
  box-shadow: 0 8px 20px rgba(21, 101, 192, .28); z-index: 3;
}

.input-row { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
/* 输入框加大加高，手机编辑方便；下拉（选择类）字号小、宽度窄 */
.input-row input, .input-row select {
  border: 2px solid #e0e0e0; border-radius: 12px; padding: 13px 14px; flex: 1; min-width: 110px;
}
.input-row input { font-size: 16px; }
.input-row select { font-size: 14px; padding: 13px 10px; }
.input-row input:focus, .input-row select:focus, textarea:focus { outline: none; border-color: var(--blue); }
textarea {
  width: 100%; border: 2px solid #e0e0e0; border-radius: 12px;
  padding: 10px 12px; font-size: 14px; min-height: 90px; resize: vertical;
  font-family: inherit;
}
.form-hint { font-size: 11px; color: var(--ink-soft); margin-top: 6px; }

.btn-primary {
  border: 0; cursor: pointer; border-radius: 999px; padding: 11px 22px;
  font-size: 14px; font-weight: 800; color: #fff;
  background: linear-gradient(135deg, #42a5f5, #1e88e5); box-shadow: 0 3px 0 #1565c0;
}
.btn-danger {
  border: 0; cursor: pointer; border-radius: 999px; padding: 6px 12px;
  font-size: 12px; font-weight: 700; color: #fff;
  background: #ef5350;
}
/* 奖励/扣分是一对，字号、内边距、粗细必须一致（.btn-danger 默认是小号行内删除按钮） */
.btn-pts {
  padding: 11px 22px; font-size: 14px; font-weight: 800;
  white-space: nowrap; min-width: 0;
}
.btn-primary.btn-pts { box-shadow: 0 3px 0 #1565c0; }
.btn-danger.btn-pts { box-shadow: 0 3px 0 #c62828; background: linear-gradient(135deg, #ef5350, #e53935); }
.btn-pts:active { transform: translateY(2px); box-shadow: none; }
.prow {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 0; border-bottom: 1px solid #f5f5f5; font-size: 14px;
}
.prow:last-child { border-bottom: 0; }
.prow .grow { flex: 1; min-width: 0; }
.prow .ok { color: #43a047; font-weight: 800; }
.prow .miss { color: #ef5350; font-weight: 800; }
/* 任务行两行布局：第一行名称+状态，第二行操作按钮 */
.prow-stack { flex-direction: column; align-items: stretch; gap: 8px; }
.prow-stack .prow-line { display: flex; align-items: center; gap: 10px; }
.prow-stack .prow-line .grow { flex: 1; min-width: 0; }
.prow-stack .prow-line .grow b { font-size: 15px; line-height: 1.4; }
.prow-stack .prow-line.actions { justify-content: flex-end; }
.prow-stack .prow-line.actions .btn-ghost, .prow-stack .prow-line.actions .btn-danger { font-size: 13px; padding: 6px 10px; }
/* 任务行内小按钮（↑↓） */
.btn-ghost.mini { padding: 3px 7px; font-size: 13px; border-radius: 8px; }
/* 家长端必做/选做分区标题 */
.prow.sec-head { border: 0; padding: 4px 0; font-size: 13px; font-weight: 800; color: var(--ink); }

/* 家长任务行可点击 + 拖动状态 */
.prow-click { cursor: pointer; }
.prow-click:active { background: #f5f5f5; }
.prow.dragging, .swipe-item.dragging { opacity: .55; background: #fff8e1; }

/* 家长端任务行：左滑露出右侧「删除」 */
.swipe-item { position: relative; overflow: hidden; }
.swipe-item > .prow { position: relative; z-index: 1; background: var(--card, #fff); transition: transform .2s ease; }
.swipe-item > .prow { border-bottom: 1px solid #f5f5f5; }        /* 包了一层后 .prow:last-child 永远命中，这里补回来 */
.swipe-item:last-child > .prow { border-bottom: 0; }
.swipe-item.open > .prow { transform: translateX(-78px); }
.swipe-del {
  position: absolute; top: 0; right: 0; bottom: 0; width: 78px;
  display: flex; align-items: center; justify-content: center;
  border: 0; background: #ef5350; color: #fff;
  font-size: 13px; font-weight: 800; letter-spacing: 2px; cursor: pointer;
}
.swipe-item:not(.open) .swipe-del { pointer-events: none; }

/* 待确认积分 */
.pending-panel { border: 2px dashed #ffb74d; }
.pend-date { font-size: 12px; color: var(--ink-soft); margin: 8px 0 2px; font-weight: 700; }
.pend-check { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.pend-check input { width: 18px; height: 18px; accent-color: #43a047; flex-shrink: 0; }
.pend-check span { flex: 1; min-width: 0; }
.btn-icon { border: 0; background: transparent; color: #ef5350; font-size: 16px; cursor: pointer; padding: 4px; }

/* 孩子端按类别分区 + 规则小抄 */
.cat-group { margin-bottom: 6px; }
.cat-head { display: flex; align-items: center; gap: 6px; font-weight: 800; font-size: 14px; padding: 12px 4px 6px; color: #455a64; }
.cat-head small { color: var(--ink-soft); font-weight: 400; font-size: 12px; }
.rules-hint { background: #fff8e1; border: 1px dashed #ffd54f; border-radius: 12px; padding: 10px 14px; margin: 10px 0 4px; font-size: 13px; }
.rules-hint summary { cursor: pointer; font-weight: 700; color: #6d4c41; }
.rules-hint ul { margin: 8px 0 2px; padding-left: 18px; line-height: 1.9; }

/* 宝可梦风 SVG 图标尺寸 */
.emoji svg { width: 26px; height: 26px; display: block; }
.cat-head svg { width: 18px; height: 18px; display: inline-block; vertical-align: -3px; }
.tabbar button .ico svg { width: 22px; height: 22px; display: block; margin: 0 auto; }
.prow svg { width: 22px; height: 22px; display: inline-block; vertical-align: -5px; }
.btn-big svg { width: 22px; height: 22px; display: inline-block; vertical-align: -4px; }
.chip svg { width: 16px; height: 16px; display: inline-block; vertical-align: -3px; }
.rules-hint summary svg { width: 18px; height: 18px; display: inline-block; vertical-align: -4px; }
.child-item svg { width: 18px; height: 18px; display: inline-block; vertical-align: -3px; }

/* 孩子端日期导航 */
.date-nav { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; row-gap: 6px; margin: 4px 0 6px; }
.date-nav .chip { white-space: nowrap; flex: 0 0 auto; }
.date-nav .date-cur { flex: 1; text-align: center; font-weight: 800; font-size: 14px; color: #455a64; white-space: nowrap; }
.date-cur .dc-short { display: none; }
.date-nav .chip:disabled { opacity: .4; cursor: default; }
/* 看历史日期时多出来的「回到今天」独占下一行整行，不把日期挤扁 */
.date-nav .chip.red { flex: 1 1 100%; }
/* 窄屏（320~380）：按钮收窄、日期换短格式（MM-DD），保证整行不换行、不堆叠 */
@media (max-width: 380px) {
  .date-nav { gap: 6px; }
  .date-nav .chip { padding: 8px 9px; font-size: 12px; }
  .date-nav .date-cur { font-size: 13px; letter-spacing: -.2px; }
  .date-cur .dc-full { display: none; }
  .date-cur .dc-short { display: inline; }
}

/* 卡牌图鉴介绍 */
.ptcg-flavor { margin: 10px 14px 0; font-size: 12px; line-height: 1.8; color: #5d4037; background: rgba(255,255,255,.75); border-radius: 10px; padding: 8px 10px; }

/* 家长端积分流水折叠面板 */
details.log-fold { border: 1px solid #e0e0e0; border-radius: 16px; padding: 12px 16px; background: #fff; }
details.log-fold summary { cursor: pointer; font-weight: 800; font-size: 15px; color: #455a64; }
details.log-fold .prow { padding: 8px 0; }
details.log-fold .when { font-size: 12px; color: var(--ink-soft); flex: none; margin-left: 6px; }

/* ---------- 全勤闪光：全屏星光雨 + 光芒 + 光环 ---------- */
/* 背景：旋转光芒 + 呼吸光晕 */
.shiny-bg { position: absolute; inset: 0; pointer-events: none; display: grid; place-items: center; }
.shiny-rays {
  width: 680px; height: 680px; max-width: 140vw; max-height: 140vw; border-radius: 50%;
  background: repeating-conic-gradient(from 0deg,
    rgba(255, 236, 120, .18) 0deg 5deg, transparent 5deg 16deg);
  animation: rays-spin 12s linear infinite;
  -webkit-mask-image: radial-gradient(circle, #000 28%, transparent 72%);
  mask-image: radial-gradient(circle, #000 28%, transparent 72%);
}
@keyframes rays-spin { to { transform: rotate(360deg); } }
.shiny-halo {
  position: absolute; left: 50%; top: 50%; width: 340px; height: 340px; margin: -170px 0 0 -170px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 224, 130, .55), rgba(255, 193, 7, .12) 55%, transparent 72%);
  animation: halo-pulse 2.4s ease-in-out infinite;
}
@keyframes halo-pulse { 0%, 100% { transform: scale(.86); opacity: .6; } 50% { transform: scale(1.22); opacity: 1; } }

/* 星光雨：从屏幕上方一路飘落到下方
   注意 animation-fill-mode: both —— 否则延迟期间会沿用元素默认样式（全亮），
   延迟一到又跳到 0% 的淡出帧，出现"露头不到 1s 就没了"的假象 */
.shiny-rain { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.shiny-rain i.rain {
  position: absolute; top: -12vh; font-style: normal; color: #fffbd6; opacity: 0;
  text-shadow: 0 0 8px #ffe082, 0 0 18px #ffd54f, 0 0 34px rgba(255, 193, 7, .85);
  animation: star-fall var(--dur, 3s) linear var(--delay, 0s) infinite;
  animation-fill-mode: both;
  will-change: transform, opacity;
}
@keyframes star-fall {
  0%   { transform: translate3d(0, -10vh, 0) scale(.35) rotate(0deg); opacity: 0; }
  10%  { opacity: 1; }
  55%  { opacity: .95; }
  100% { transform: translate3d(var(--drift, 0px), 112vh, 0) scale(1.05) rotate(240deg); opacity: 0; }
}
/* 宝可梦周围扩散的光环 */
.shiny-ring {
  position: absolute; left: 50%; top: 50%; width: 130px; height: 130px;
  margin: -65px 0 0 -65px; border: 3px solid rgba(255, 235, 130, .95); border-radius: 50%;
  pointer-events: none; animation: ring-out 2.2s ease-out infinite;
}
.shiny-ring.r2 { animation-delay: 1.1s; border-color: rgba(255, 255, 255, .7); }
@keyframes ring-out { 0% { transform: scale(.55); opacity: .95; } 100% { transform: scale(2.5); opacity: 0; } }
/* 闪光宝可梦：描边发光 + 轻轻漂浮（用 .overlay.gold 提高优先级，压过 .ov-mon.reveal） */
.overlay.gold .ov-mon.shiny-mon {
  filter: drop-shadow(0 0 14px #ffe082) drop-shadow(0 0 34px rgba(255, 193, 7, .8)) saturate(1.25) brightness(1.08);
  animation: mon-reveal .7s cubic-bezier(.2, 1.6, .4, 1) forwards,
             mon-float 2.8s ease-in-out .7s infinite;
}
@keyframes mon-float { 0%, 100% { transform: translateY(0) scale(1); } 50% { transform: translateY(-8px) scale(1.03); } }
/* SHINY! 徽章 */
.ov-badge {
  font-size: 12px; font-weight: 900; letter-spacing: .28em; color: #3e2723;
  background: linear-gradient(135deg, #ffe082, #ffb300);
  padding: 4px 14px; border-radius: 999px; margin-top: 2px;
  box-shadow: 0 0 22px rgba(255, 193, 7, .8);
  animation: badge-pop .5s cubic-bezier(.2, 1.6, .4, 1) .15s both;
}
@keyframes badge-pop { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }
/* 金色流光标题 */
.overlay.gold .ov-title {
  background: linear-gradient(90deg, #fff8e1, #ffd54f, #fff8e1, #ffb300, #fff8e1);
  background-size: 300% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  text-shadow: none; filter: drop-shadow(0 2px 10px rgba(255, 193, 7, .6));
  animation: title-shine 2.4s linear infinite;
}
@keyframes title-shine { to { background-position: 300% 0; } }
.overlay.gold .ov-sub { color: #ffe9b5; }

/* 日历 */
.cal-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.cal-head b { font-size: 16px; }
.cal-nav { border: 0; background: #eceff1; width: 34px; height: 34px; border-radius: 10px; font-size: 16px; cursor: pointer; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.cal-dow { text-align: center; font-size: 11px; color: var(--ink-soft); padding: 4px 0; }
.cal-day {
  aspect-ratio: 1; border-radius: 10px; background: #f5f5f5;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-size: 12px; position: relative;
}
.cal-day.today { outline: 2px solid var(--blue); }
.cal-day .dot { width: 10px; height: 10px; border-radius: 50%; margin-top: 2px; }
/* 颜色不限定在 .cal-day 里：下面的图例也用同一套圆点，避免两处各写一遍颜色 */
.dot.full { background: var(--green); }
.dot.part { background: var(--yellow); }
.dot.none { background: #ef9a9a; }
/* 那天本来就没有这类任务（还没布置/已停用）：灰色，别和"没做"混为一谈 */
.dot.na { background: #e0e0e0; }
/* 日历维度切换（必做全清 / 选做全清）
   刻意不用圆形色块图标：圆点在下面的日历格子里已经表示"完成状态"了，
   同一块面板里同一种颜色不能有两个意思。这里靠整块底色的红/绿区分必做/选做。 */
.cal-toggle { display: flex; gap: 8px; margin-bottom: 10px; }
.cal-tab {
  flex: 1; border: 1.5px solid #e3e8ef; background: #fff; border-radius: 10px;
  padding: 8px 4px; font-size: 13px; font-weight: 800; color: var(--ink-soft); cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.cal-tab.req.on { border-color: #ef5350; background: #ffebee; color: #c62828; }
.cal-tab.opt.on { border-color: #66bb6a; background: #e8f5e9; color: #2e7d32; }
/* 图例：把圆点颜色的含义集中说明一次（格子里就不再重复解释） */
.cal-legend {
  display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 10px;
  font-size: 11px; color: var(--ink-soft);
}
.cal-legend span { display: inline-flex; align-items: center; gap: 4px; }
.cal-legend .dot { display: inline-block; margin-top: 0; width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.cal-day.empty { background: transparent; }
/* 未来的日子：淡一点、不判成败（还没到，标红点会像在说孩子没做） */
.cal-day.future { background: #fafafa; color: #b0bec5; }
.cal-day.future .dot { background: transparent; border: 1px dashed #cfd8dc; }

/* 密码弹层 */
.modal-mask {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(38, 50, 56, .55); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; padding: 24px;
}
.modal {
  background: #fff; border-radius: 20px; padding: 18px 20px; width: 100%; max-width: 400px;
  text-align: left; border: 1px solid #f0f2f5; box-shadow: 0 16px 40px rgba(31,64,98,.16);
  max-height: calc(100vh - 48px); overflow-y: auto;   /* 内容多时弹窗内部滚动，不超出屏幕 */
}
.modal h3 {
  font-size: 15px; margin: 0 0 14px; display: flex; align-items: center; gap: 6px;
  color: var(--ink); padding-bottom: 10px; border-bottom: 2px solid #eef2f6;
}
.modal label { display: block; font-size: 11px; color: var(--ink-soft); margin: 8px 0 3px; }
.modal input, .modal select, .modal textarea {
  width: 100%; box-sizing: border-box; border: 1.5px solid #e3e8ef; border-radius: 9px;
  padding: 8px 10px; font-size: 13px; margin-bottom: 6px; background: #fafbfd;
  font-family: inherit; text-align: left; transition: border-color .15s, background .15s;
}
.modal input:focus, .modal select:focus, .modal textarea:focus {
  outline: none; border-color: var(--blue); background: #fff;
}
.modal select { height: 36px; padding: 0 8px; font-size: 13px; }
.modal textarea { min-height: 60px; resize: vertical; }
.modal .row { display: flex; gap: 10px; }
.modal .row button { flex: 1; }
.modal .btn-primary, .modal .btn-cancel, .modal .btn-danger { font-size: 13px; padding: 9px 16px; }

/* 自绘确认框 / 密码框（替代原生 confirm/prompt：预览面板与内嵌 WebView 禁用了原生弹窗） */
.modal .ask-msg { font-size: 13px; line-height: 1.65; color: var(--ink); word-break: break-word; }
.modal .pw-err { min-height: 16px; margin: 2px 0 0; font-size: 11.5px; color: #e53935; font-weight: 700; text-align: center; }
.modal.shake { animation: modal-shake .32s ease; }
@keyframes modal-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-7px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(3px); }
}

/* 任务详情弹窗：信息表（截止日期等） */

/* 必做/选做 进度条弹出的任务清单 */
.pd-list { margin-top: 10px; max-height: 52vh; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.pd-row { display: flex; align-items: center; gap: 8px; padding: 10px 8px; border-bottom: 1px solid #f5f5f5; border-radius: 10px; cursor: pointer; font-size: 13px; transition: background .12s; }
.pd-row:active { background: #f1f8e9; }
.pd-ico { display: flex; flex: 0 0 24px; align-items: center; justify-content: center; width: 24px; height: 24px; }
.pd-ico svg, .pd-ico img { width: 22px; height: 22px; }
.pd-name { display: flex; flex: 1 1 auto; flex-direction: column; gap: 2px; min-width: 0; font-weight: 700; color: var(--ink); }
.pd-row.ok .pd-name { color: #90a4ae; }
.pd-dl { font-size: 11px; font-weight: 500; color: var(--ink-soft); }
.pd-pts { flex: 0 0 auto; font-size: 12px; font-weight: 800; color: #f57f17; }
.pd-st { flex: 0 0 auto; padding: 3px 8px; border-radius: 999px; background: #eceff1; color: #78909c; font-size: 11px; font-weight: 700; white-space: nowrap; }
.pd-st.ok { background: #e8f5e9; color: #2e7d32; }
.pd-st.pend { background: #e3f2fd; color: #1565c0; }
.pd-foot { margin-top: 10px; font-size: 11px; color: var(--ink-soft); text-align: center; }
.btn-cancel { border: 0; border-radius: 999px; padding: 12px; background: #eceff1; color: var(--ink-soft); cursor: pointer; font-weight: 700; }
.shake-x { animation: shake-x .4s; }
@keyframes shake-x { 20%,60% { transform: translateX(-8px); } 40%,80% { transform: translateX(8px); } }

/* ---------- 全屏动画遮罩 ---------- */
.overlay {
  position: fixed; inset: 0; z-index: 100;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: radial-gradient(circle at 50% 40%, #1a237e, #000 75%);
  color: #fff;
}
.overlay.gold {
  background: radial-gradient(circle at 50% 42%, #2a1b52 0%, #140b28 46%, #05030a 100%);
  overflow: hidden;
}
.overlay.hidden { display: none; }

.ov-stage { position: relative; width: 260px; height: 260px; display: grid; place-items: center; }
.ov-stage img { width: 160px; height: 160px; image-rendering: pixelated; }

.catch-ball {
  width: 72px; height: 72px; border-radius: 50%; position: absolute;
  background: linear-gradient(#e53935 50%, #fff 50%);
  border: 4px solid #263238; box-shadow: 0 0 24px rgba(255, 255, 255, .35);
}
.catch-ball::before { content: ''; position: absolute; top: 50%; left: -4px; right: -4px; height: 7px; transform: translateY(-50%); background: #263238; }
.catch-ball::after { content: ''; position: absolute; top: 50%; left: 50%; width: 22px; height: 22px; border-radius: 50%; transform: translate(-50%, -50%); background: #fff; border: 4px solid #263238; }

.catch-ball.fly { animation: ball-fly .9s cubic-bezier(.3, .8, .4, 1) forwards; }
@keyframes ball-fly {
  0% { transform: translate(-160px, 140px) rotate(-360deg) scale(.6); }
  100% { transform: translate(0, 0) rotate(0) scale(1); }
}
.catch-ball.shaking { animation: ball-shake 1.4s ease-in-out forwards; }
@keyframes ball-shake {
  0%, 28%, 56% { transform: rotate(0); }
  10%, 38%, 66% { transform: rotate(-24deg); }
  18%, 48% { transform: rotate(24deg); }
  85% { transform: rotate(0) scale(1); }
  100% { transform: rotate(0) scale(1); opacity: 0; filter: brightness(3); }
}
.ov-mon { opacity: 0; transform: scale(0); }
.ov-mon.reveal { animation: mon-reveal .7s cubic-bezier(.2, 1.6, .4, 1) forwards; }
@keyframes mon-reveal { to { opacity: 1; transform: scale(1); } }
.ov-title { font-size: 26px; font-weight: 900; margin-top: 8px; text-shadow: 0 2px 12px rgba(255, 255, 255, .45); }
.ov-sub { font-size: 14px; opacity: .85; margin-top: 6px; min-height: 20px; max-width: 86%; line-height: 1.5; padding: 0 6px; }
.ov-skip {
  position: absolute; bottom: 40px; border: 0; cursor: pointer;
  background: rgba(255, 255, 255, .16); color: #fff;
  border-radius: 999px; padding: 10px 26px; font-size: 14px;
}

/* 进化动画 */
.evo-mon { filter: brightness(0); transition: filter .3s; }
.evo-mon.glowing { animation: evo-glow 1.8s ease-in-out forwards; }
@keyframes evo-glow {
  0%, 100% { filter: brightness(0); transform: scale(1); }
  10%, 50% { transform: scale(1.05); }
  30% { transform: scale(.96); }
  60% { transform: scale(1.1); }
  80% { filter: brightness(0) invert(1); transform: scale(1.15); }
  100% { filter: brightness(6) blur(6px); transform: scale(1.3); opacity: 0; }
}
.ov-flash {
  position: absolute; inset: 0; background: #fff; opacity: 0;
  pointer-events: none;
}
.ov-flash.go { animation: evo-flash .8s ease-out forwards; }
@keyframes evo-flash { 0% { opacity: 0; } 40% { opacity: 1; } 100% { opacity: 0; } }

/* 升级金光 */
.levelup-wrap { text-align: center; }
.levelup-wrap .lv-txt {
  font-size: 40px; font-weight: 900; color: #ffd54f;
  text-shadow: 0 0 18px #ffb300, 0 3px 0 #b8860b;
  animation: lv-pop .6s cubic-bezier(.2, 1.8, .4, 1);
}
@keyframes lv-pop { 0% { transform: scale(0) rotate(-14deg); } 100% { transform: scale(1) rotate(0); } }
.levelup-wrap img { width: 120px; height: 120px; image-rendering: pixelated; margin: 10px 0; filter: drop-shadow(0 0 16px #ffb300); }

/* toast */
.toast {
  position: fixed; left: 50%; bottom: 110px; transform: translateX(-50%);
  z-index: 120; background: rgba(38, 50, 56, .92); color: #fff;
  padding: 12px 22px; border-radius: 999px; font-size: 14px; font-weight: 700;
  box-shadow: var(--shadow); animation: toast-in .3s ease; max-width: 86vw; text-align: center;
}
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 14px); } }

/* 喂养选择弹窗 */
.feed-opts { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; margin-top: 14px; }
.feed-opts button {
  border: 0; cursor: pointer; border-radius: 14px; padding: 14px 18px;
  font-size: 16px; font-weight: 800; color: #fff;
  background: linear-gradient(135deg, #7e57c2, #5e35b1); box-shadow: 0 3px 0 #4527a0;
}
.feed-opts button:disabled { filter: grayscale(1); opacity: .5; box-shadow: none; cursor: not-allowed; }
/* 「刚好喂到下一阶段」一键按钮：单独占一行 */
.feed-opts button.feed-exact { flex: 1 1 100%; background: linear-gradient(135deg, #26c6da, #00acc1); box-shadow: 0 3px 0 #00838f; }
.feed-opts button.feed-exact:disabled { background: #eceff1; color: #90a4ae; }
/* 「全部」按钮：低调一点 */
.feed-opts button.feed-all { background: linear-gradient(135deg, #90a4ae, #607d8b); box-shadow: 0 3px 0 #455a64; }
/* 喂糖果弹窗：余额/经验概览 */
.feed-sub { font-size: 12px; color: #607d8b; margin: 0 0 2px; text-align: center; line-height: 1.6; }
.feed-sub b { color: #5e35b1; }
/* 自定义积分数输入 */
.feed-custom { display: flex; gap: 8px; margin-top: 12px; }
.feed-custom input {
  flex: 1; min-width: 0; width: auto; margin: 0; box-sizing: border-box;
  border: 1.5px solid #e3e8ef; border-radius: 12px; padding: 11px 12px;
  font-size: 15px; font-weight: 700; text-align: center; font-family: inherit; background: #fafbfd;
}
.feed-custom input:focus { outline: none; border-color: #7e57c2; background: #fff; }
.feed-go {
  flex: 0 0 88px; border: 0; cursor: pointer; border-radius: 12px;
  font-size: 15px; font-weight: 800; color: #fff;
  background: linear-gradient(135deg, #7e57c2, #5e35b1); box-shadow: 0 3px 0 #4527a0;
}
.feed-go:active { transform: translateY(2px); box-shadow: none; }
.feed-hint { font-size: 11px; color: #90a4ae; text-align: center; margin-top: 10px; line-height: 1.6; }

/* 空状态 */
.empty-tip { text-align: center; color: var(--ink-soft); padding: 30px 0; font-size: 14px; }

/* ---------- 本周任务进度按钮 ---------- */
.weekly-card { border: 2px solid #ffcc80; }
.prog-btns { display: flex; gap: 6px; flex: none; flex-wrap: wrap; }
.prog-btns .btn-done.prog {
  padding: 10px 12px; font-size: 14px;
  background: linear-gradient(135deg, #ffb74d, #fb8c00); box-shadow: 0 3px 0 #e65100;
}
.prog-btns .btn-done.prog:active { transform: translateY(3px); box-shadow: none; }

/* ---------- 宝可梦卡牌网格 ---------- */
.pm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 12px; }
.pm-card-mini {
  background: var(--card); border-radius: 16px; box-shadow: var(--shadow);
  padding: 8px 8px 10px; text-align: center; cursor: pointer;
  transition: transform .15s;
}
.pm-card-mini:active { transform: scale(.95); }
.pm-card-mini.shiny { background: linear-gradient(160deg, #fffde7, #ffecb3); box-shadow: 0 4px 18px rgba(255, 193, 7, .35); }
/* 闪耀小卡：金色呼吸边框 + 全息扫光（明显区别于普通卡） */
.pm-card-mini.shiny .mini-frame {
  box-shadow: 0 0 0 2px rgba(255, 213, 79, .7), 0 0 16px rgba(255, 193, 7, .55);
  animation: mini-shiny-glow 2.6s ease-in-out infinite;
}
@keyframes mini-shiny-glow {
  50% { box-shadow: 0 0 0 3px rgba(255, 241, 170, .95), 0 0 26px rgba(255, 193, 7, .85); }
}
.pm-card-mini.shiny .mini-frame::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(115deg, transparent 32%, rgba(255,255,255,.5) 44%,
              rgba(180,240,255,.35) 50%, rgba(255,200,255,.32) 56%, transparent 68%);
  background-size: 260% 260%;
  animation: mini-holo 3.8s linear infinite;
  mix-blend-mode: screen;
}
@keyframes mini-holo { 0% { background-position: 210% 0; } 100% { background-position: -110% 0; } }
/* 角标要盖在全息层上面 */
.mini-shiny, .mini-lead, .mini-lv-badge, .mini-pick { z-index: 2; }
.mini-frame {
  position: relative; border-radius: 12px; overflow: hidden;
  aspect-ratio: 1 / 1; border: 3px solid var(--tc, #a8a878);
}
.mini-frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mini-shiny { position: absolute; top: 3px; right: 5px; font-size: 16px; animation: twinkle 1.2s infinite; }
.mini-lead { position: absolute; top: 3px; left: 5px; font-size: 16px; }
.mini-lv-badge {
  position: absolute; bottom: 4px; right: 4px;
  background: rgba(0,0,0,.65); color: #ffd54f; font-size: 11px; font-weight: 800;
  padding: 2px 7px; border-radius: 999px;
}
/* 第一行：图鉴编号 + 属性小胶囊 + 名字；第二行：获取时间 */
.mini-line { display: flex; align-items: center; justify-content: center; gap: 4px; margin-top: 7px; min-width: 0; }
.mini-no { flex: 0 0 auto; font-size: 9px; font-weight: 800; color: #90a4ae; letter-spacing: .2px; }
.mini-type {
  flex: 0 0 auto; font-size: 9px; font-weight: 800; color: #fff; line-height: 1;
  padding: 3px 5px; border-radius: 999px; letter-spacing: .3px;
}
.mini-name { font-weight: 800; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.mini-time { font-size: 10px; color: #90a4ae; margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mini-time .ball-ico { display: inline-block; width: 11px; height: 11px; vertical-align: -1px; margin-right: 3px; }
.mini-time .ball-ico svg { display: block; width: 100%; height: 100%; }
@keyframes twinkle { 50% { opacity: .35; transform: scale(.85); } }

/* ✨ 闪耀卡：宝可梦页最上方的一条奖励提示（有库存才出现），点「使用」进入选卡态 */
.shiny-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 13px; margin-bottom: 12px; border-radius: 16px;
  background: linear-gradient(135deg, #fff8e1, #ffe6a8);
  border: 2px solid #ffd54f; box-shadow: 0 6px 16px rgba(255, 193, 7, .18);
}
.shiny-bar-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.shiny-bar-main b { font-size: 15px; color: #6d4c00; white-space: nowrap; }
.shiny-bar-main span { font-size: 12px; color: #8d6e2f; line-height: 1.35; }
.shiny-btn {
  flex: 0 0 auto; border: 0; cursor: pointer; border-radius: 999px; padding: 9px 18px;
  font-size: 14px; font-weight: 800; color: #5d4200; font-family: inherit;
  background: linear-gradient(135deg, #ffd54f, #ffb300);
  box-shadow: 0 4px 12px rgba(255, 179, 0, .35);
}
.shiny-btn:active { transform: scale(.95); }
.shiny-btn.ghost { background: #fff; color: #8d6e2f; border: 1px solid #ffd54f; box-shadow: none; }
.shiny-bar.picking { background: linear-gradient(135deg, #fffdf3, #ffefc2); box-shadow: 0 0 0 3px rgba(255, 193, 7, .22); }
/* 选卡态：可选的卡描金边，已闪的卡置灰不可点 */
.pm-card-mini.picking { outline: 2px dashed #ffb300; outline-offset: 2px; }
.pm-card-mini.picking.locked { opacity: .35; filter: grayscale(.7); outline-color: #cfd8dc; cursor: not-allowed; }
.mini-pick {
  position: absolute; left: 50%; bottom: 5px; transform: translateX(-50%);
  background: rgba(255, 179, 0, .95); color: #fff; font-size: 10px; font-weight: 800;
  padding: 2px 8px; border-radius: 999px; white-space: nowrap;
}
/* 选卡态下藏掉阶段角标，否则会和「闪耀吧！✨」叠在一起 */
.pm-card-mini.picking .mini-lv-badge { display: none; }

/* ---------- 连续必做全清（孩子端任务页最下方） ---------- */
.streak-card { margin-top: 4px; }
.streak-card .streak-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; font-size: 13px; margin-bottom: 6px; }
.streak-card .streak-head b { font-size: 14px; }
.streak-card .streak-head span { color: var(--ink-soft); font-weight: 700; }
.streak-row { display: flex; align-items: center; gap: 10px; }
.streak-row .progress-track { flex: 1; }
.streak-btn {
  flex: 0 0 auto; border: 0; border-radius: 999px; cursor: pointer;
  font-size: 12px; font-weight: 800; padding: 8px 12px; white-space: nowrap;
  background: #eceff1; color: #78909c;
}
.streak-btn:disabled { cursor: default; }
.streak-btn.ready {
  background: linear-gradient(135deg, #ffb74d, #fb8c00); color: #fff;
  box-shadow: 0 3px 0 #ef6c00; animation: streak-pulse 1.1s ease-in-out infinite;
}
.streak-btn.ready:active { transform: translateY(2px); box-shadow: none; }
@keyframes streak-pulse {
  0%, 100% { transform: scale(1); box-shadow: 0 3px 0 #ef6c00, 0 0 0 0 rgba(251, 140, 0, .55); }
  50% { transform: scale(1.05); box-shadow: 0 3px 0 #ef6c00, 0 0 0 9px rgba(251, 140, 0, 0); }
}
.streak-tip { font-size: 11px; color: var(--ink-soft); line-height: 1.5; margin-top: 7px; }
.streak-card.ready { box-shadow: 0 0 0 2px rgba(255, 183, 77, .5), var(--shadow); }

/* 达标庆祝：整屏奖杯 */
.streak-fx { text-align: center; color: #fff; padding: 20px; }
.streak-fx-badge { font-size: 84px; line-height: 1; animation: streak-pop .6s cubic-bezier(.2, 1.5, .4, 1) both; }
.streak-fx-title { font-size: 24px; font-weight: 900; margin-top: 12px; text-shadow: 0 2px 12px rgba(0, 0, 0, .35); }
.streak-fx-sub { font-size: 14px; opacity: .92; margin-top: 8px; line-height: 1.5; }
.streak-fx .catch-tap { margin-top: 20px; font-size: 13px; opacity: .6; }
@keyframes streak-pop { from { transform: scale(.3) rotate(-12deg); opacity: 0; } }

/* ---------- 卡牌详情（PTCG 风格） ---------- */
.overlay.card-view {
  background: radial-gradient(circle at 50% 30%, #2a2a45, #0b0b1a 80%);
  /* 卡面内容变多（4 个招式 + 说明）后可能高过屏幕：顶部对齐 + 可滚动，靠 margin:auto 保持垂直居中 */
  justify-content: flex-start; overflow-y: auto; padding: 16px 0;
  -webkit-overflow-scrolling: touch;
}
.overlay.card-view .ptcg { margin: auto 0; flex: 0 0 auto; }
.ptcg {
  width: min(320px, 90vw); border-radius: 20px; padding: 14px 14px 12px;
  border: 3px solid var(--tc, #a8a878);
  background: linear-gradient(160deg, var(--bg1, #eceadf), var(--bg2, #a8a878));
  box-shadow: 0 12px 44px rgba(0,0,0,.6), inset 0 0 0 2px rgba(255,255,255,.35);
  animation: card-flip .5s cubic-bezier(.2, 1.4, .4, 1);
}
@keyframes card-flip {
  0% { transform: perspective(900px) rotateY(95deg) scale(.55); opacity: 0; }
  100% { transform: perspective(900px) rotateY(0) scale(1); opacity: 1; }
}
.ptcg-top { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.ptcg-name { font-size: 22px; font-weight: 900; color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,.35); flex: 1; }
.ptcg-shiny { font-size: 12px; font-weight: 800; color: #ffd54f; background: rgba(0,0,0,.35); padding: 3px 9px; border-radius: 999px; }
.ptcg-lv { font-size: 15px; font-weight: 900; color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,.3); }
.ptcg-art {
  position: relative; border-radius: 14px; overflow: hidden;
  border: 2px solid rgba(255,255,255,.5); background: rgba(255,255,255,.25);
  aspect-ratio: 1 / 1; display: grid; place-items: center;
}
.ptcg-art img { width: 100%; height: 100%; object-fit: contain; }
.ptcg-type {
  position: absolute; bottom: 8px; left: 8px;
  background: var(--tc, #a8a878); color: #fff; font-weight: 800;
  font-size: 12px; padding: 3px 10px; border-radius: 999px;
  box-shadow: 0 2px 6px rgba(0,0,0,.35);
}
/* 闪光卡面的星星特效
   旧实现只有一个伪元素 + translateY(140%)：百分比是按伪元素自身高度算的（一行字≈30px），
   实际只下移四十来像素，星星基本停在卡面上方，所以"露头几帧就没了"。
   现在：多颗星各自从卡面上方落到卡面下方（px 位移），负延迟让它一打开就铺满。 */
.ptcg-glitter { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.ptcg-glitter i {
  position: absolute; left: var(--x, 50%); top: 0;
  font-style: normal; color: #fff8d0; opacity: 0; line-height: 1;
  text-shadow: 0 0 8px #ffe082, 0 0 18px #ffb300;
  animation: card-spark var(--dur, 2.6s) linear var(--delay, 0s) infinite;
  animation-fill-mode: both;
  will-change: transform, opacity;
}
@keyframes card-spark {
  0%   { transform: translate3d(0, -24px, 0) scale(.35) rotate(0deg); opacity: 0; }
  12%  { opacity: 1; }
  70%  { opacity: .95; }
  100% { transform: translate3d(var(--drift, 0px), var(--fall, 320px), 0) scale(1.05) rotate(220deg); opacity: 0; }
}
/* 全息光带：斜向扫过卡面 */
.ptcg-glitter::after {
  content: ''; position: absolute; top: -60%; left: 0; width: 45%; height: 220%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .62), rgba(255, 241, 170, .35), transparent);
  transform: rotate(16deg) translateX(-160%);
  animation: holo-sweep 3.4s ease-in-out infinite;
}
@keyframes holo-sweep {
  0%         { transform: rotate(16deg) translateX(-160%); opacity: 0; }
  12%        { opacity: 1; }
  60%, 100%  { transform: rotate(16deg) translateX(320%); opacity: 0; }
}
/* 闪光卡面：立绘发光 + 轻微上浮 */
.ptcg-art.shiny-art img {
  filter: drop-shadow(0 0 10px #ffe082) drop-shadow(0 0 26px rgba(255, 193, 7, .8)) saturate(1.15) brightness(1.05);
  animation: art-float 3.2s ease-in-out infinite;
}
/* 闪耀卡整体：金色呼吸光晕（让"进入闪耀形态"一眼可见） */
.ptcg.shiny-card {
  box-shadow: 0 12px 44px rgba(0,0,0,.6), 0 0 0 2px rgba(255,241,170,.65),
              0 0 34px rgba(255,193,7,.6), inset 0 0 0 2px rgba(255,255,255,.35);
  animation: card-flip .5s cubic-bezier(.2,1.4,.4,1), shiny-card-glow 2.8s ease-in-out infinite .6s;
}
@keyframes shiny-card-glow {
  0%, 100% { box-shadow: 0 12px 44px rgba(0,0,0,.6), 0 0 0 2px rgba(255,241,170,.6),
                         0 0 30px rgba(255,193,7,.5), inset 0 0 0 2px rgba(255,255,255,.35); }
  50%      { box-shadow: 0 12px 44px rgba(0,0,0,.6), 0 0 0 3px rgba(255,241,170,1),
                         0 0 60px rgba(255,193,7,.9), inset 0 0 0 2px rgba(255,255,255,.5); }
}
/* 闪耀造型：切到异色像素动图时的展示（放大不糊、金色底衬） */
.ptcg-art.sprite-art {
  background: radial-gradient(circle at 50% 42%, #fffdf2 0%, rgba(255,241,170,.75) 45%, rgba(255,193,7,.28) 100%);
}
.ptcg-art.sprite-art img {
  object-fit: contain; padding: 9%;
  image-rendering: pixelated;
  filter: drop-shadow(0 0 10px #ffe082) drop-shadow(0 0 26px rgba(255,193,7,.8));
  animation: art-float 3.2s ease-in-out infinite;
}
/* 详情卡右上角：造型切换（立绘 / 异色动图 / 场景卡） */
.art-toggle {
  position: absolute; top: 8px; right: 8px; z-index: 4;
  border: 0; cursor: pointer; font-size: 11px; font-weight: 800;
  padding: 5px 10px; border-radius: 999px;
  background: rgba(255,255,255,.92); color: #b8860b;
  box-shadow: 0 2px 10px rgba(255,193,7,.55);
}
.art-toggle:active { transform: scale(.95); }
/* 场景卡：整张中文卡面，保持完整不裁切（黑底衬托），并去掉立绘的发光/浮动 */
.ptcg-art.scene-art { background: radial-gradient(circle at 50% 40%, #2a3040, #10131a 75%); }
.ptcg-art.scene-art img,
.ptcg-art.shiny-art.scene-art img {
  width: 100%; height: 100%; object-fit: contain;
  padding: 0; filter: none; animation: none;
  border-radius: 8px;
  box-shadow: 0 6px 22px rgba(0,0,0,.6);
}
/* 场景卡模式：卡面上已经印了招式/说明 → 隐藏 App 自己的招式区和图鉴介绍，
   并让图片按自身比例撑高（不再被正方形画框裁切），整张卡完整显示。
   顶部那一行（名字 / ✨闪耀形态 / 阶段）**保留**：这是 App 自己抽到的宝可梦身份，
   不是卡面印的内容，闪耀形态尤其要靠它一眼认出来。
   卡牌外形（宽度、左右内边距、圆角、边框）一律沿用 .ptcg 不动：切换造型时整张卡不许变宽/跳，
   图片才能保持素材本身的 400×559（0.7156）比例。
   tests/ui-guards.test.js 守着「别给 .ptcg.scene-mode 设 width / 左右 padding」。 */
.ptcg.scene-mode .ptcg-moves,
.ptcg.scene-mode .ptcg-flavor { display: none; }
/* 名字行下面留一条空带放造型按钮：卡图铺满后按钮会压住卡面右上角的 HP / 属性。
   只动纵向间距，横向宽度不变（测试守着 width / 左右 padding）。 */
.ptcg.scene-mode .ptcg-top { margin-bottom: 40px; }
.ptcg.scene-mode .ptcg-art {
  aspect-ratio: auto; height: auto; display: block;
  /* 边框只改颜色不改宽度：少掉 2px 边框会让图片跟着宽 4px，切换瞬间有细微位移 */
  border-color: transparent; background: transparent; overflow: visible;
}
.ptcg.scene-mode .ptcg-art img {
  width: 100%; height: auto; object-fit: contain;
  border-radius: 12px;
  box-shadow: 0 6px 22px rgba(0,0,0,.55);
}
/* 闪耀形态 + 场景卡：金色卡框继续包住整张中文卡面。
   .ptcg.shiny-card 的呼吸光晕本来就在最外层，这里再给卡图补一圈金边 + 柔光，
   否则切到场景卡（图片会盖掉 .ptcg-art 的底和边）就看不出这是闪耀形态了。
   注意别用 art-float 上下浮动：整张卡面在动会显得比例在飘，只做光晕呼吸。 */
.ptcg.shiny-card.scene-mode .ptcg-art { border-color: rgba(255,241,170,.9); }
.ptcg.shiny-card.scene-mode .ptcg-art img {
  filter: drop-shadow(0 0 8px rgba(255,224,130,.9)) drop-shadow(0 0 22px rgba(255,179,0,.6))
          saturate(1.14) brightness(1.05);
  animation: shiny-scene-glow 2.8s ease-in-out infinite;
}
@keyframes shiny-scene-glow {
  0%, 100% {
    filter: drop-shadow(0 0 6px rgba(255,224,130,.75)) drop-shadow(0 0 16px rgba(255,179,0,.5))
            saturate(1.1) brightness(1.03);
  }
  50% {
    filter: drop-shadow(0 0 14px rgba(255,241,170,1)) drop-shadow(0 0 34px rgba(255,193,7,.85))
            saturate(1.18) brightness(1.07);
  }
}
/* 场景卡模式下卡图铺满整张卡，按钮会正好压住卡面右上角的 HP / 属性：
   挪到名字行下方那条空带里（.ptcg-art 在场景卡模式是 overflow: visible），顺便收小一点 */
.ptcg.scene-mode .art-toggle {
  top: -32px; right: 0;
  padding: 4px 9px; font-size: 10px;
}
@keyframes art-float {
  0%, 100% { transform: translateY(0) scale(1); }
  50%      { transform: translateY(-6px) scale(1.03); }
}
/* ---------- 卡面属性特效（按宝可梦属性自动匹配） ----------
   全部是纯 CSS 无限循环：伪元素 + 重复渐变当粒子，不用 JS 定时器，手机上也不掉帧。
   位移统一用 background-position，而且位移量都是 background-size 的整数倍，
   这样循环起来是无缝的，不会出现"跑完一遍就断掉"的观感。 */
.ptcg-fx { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.ptcg-fx::before, .ptcg-fx::after { content: ''; position: absolute; inset: -15%; }
@keyframes fx-breathe {
  0%, 100% { opacity: .35; transform: scale(.96); }
  50%      { opacity: .85; transform: scale(1.04); }
}
/* 火：火星往上飘 + 底部暖光 */
.fx-ember::before {
  background-image:
    radial-gradient(circle, rgba(255, 214, 130, .95) 0, rgba(255, 214, 130, .95) 2px, transparent 2.6px),
    radial-gradient(circle, rgba(255, 138, 40, .9) 0, rgba(255, 138, 40, .9) 1.6px, transparent 2.2px),
    radial-gradient(circle, rgba(255, 246, 200, .9) 0, rgba(255, 246, 200, .9) 2.6px, transparent 3.2px);
  background-size: 56px 88px, 40px 66px, 80px 110px;
  background-position: 0 0, 18px 24px, -12px 40px;
  animation: fx-ember-rise 4.2s linear infinite;
  opacity: .95;
}
@keyframes fx-ember-rise {
  from { background-position: 0 0, 18px 24px, -12px 40px; }
  to   { background-position: 0 -176px, 18px -198px, -12px -220px; }
}
.fx-ember::after {
  background: radial-gradient(circle at 50% 104%, rgba(255, 120, 20, .32), transparent 62%);
  animation: fx-breathe 3.4s ease-in-out infinite;
}
/* 水：整张卡都是水 —— 浪花纹平铺 + 水下蓝调 + 水滴波纹从底部扩散 + 上升气泡 + 水光扫过
   之前那版只压底部 30%，看着像"站在水边"，跟别的属性铺满整张卡不搭。
   现在照日本「青海波」的思路：重复浪花纹当底，白线下面垫一层深蓝描边，
   浅蓝卡面上也看得见；纹样位移都取 tile 的整数倍，循环无缝。 */
.fx-wave::before {
  inset: -12%;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='232' height='96' viewBox='0 0 232 96'%3E%3Cg fill='none' stroke-linecap='round'%3E%3Cpath d='M0 30 Q29 12 58 30 T116 30 T174 30 T232 30' stroke='%231a5cbf' stroke-opacity='.14' stroke-width='6'/%3E%3Cpath d='M0 30 Q29 12 58 30 T116 30 T174 30 T232 30' stroke='%23ffffff' stroke-opacity='.62' stroke-width='1.8'/%3E%3Cpath d='M0 68 Q29 50 58 68 T116 68 T174 68 T232 68' stroke='%231a5cbf' stroke-opacity='.11' stroke-width='6'/%3E%3Cpath d='M0 68 Q29 50 58 68 T116 68 T174 68 T232 68' stroke='%23ffffff' stroke-opacity='.38' stroke-width='1.5'/%3E%3C/g%3E%3C/svg%3E"),
    radial-gradient(58% 40% at 28% 20%, rgba(255, 255, 255, .30), rgba(255, 255, 255, 0) 72%),
    radial-gradient(46% 34% at 74% 64%, rgba(190, 240, 255, .26), rgba(190, 240, 255, 0) 74%),
    radial-gradient(120% 88% at 50% 118%, rgba(16, 104, 196, .40), rgba(16, 104, 196, 0) 74%),
    linear-gradient(180deg, rgba(160, 220, 255, .12) 0%, rgba(96, 178, 245, .09) 45%, rgba(28, 118, 208, .24) 100%);
  background-size: 232px 96px, 100% 100%, 100% 100%, 100% 100%, 100% 100%;
  background-repeat: repeat, no-repeat, no-repeat, no-repeat, no-repeat;
  background-position: 0 0, 0 0, 0 0, 0 0, 0 0;
  animation: fx-water-drift 22s linear infinite, fx-water-glow 7s ease-in-out infinite;
}
@keyframes fx-water-drift {
  from { background-position: 0 0, 0 0, 0 0, 0 0, 0 0; }
  to   { background-position: 464px -192px, 0 0, 0 0, 0 0, 0 0; }   /* 2 个 tile，无缝 */
}
@keyframes fx-water-glow {
  0%, 100% { opacity: .82; }
  50%      { opacity: 1; }
}
/* 水滴波纹：从底部水面一圈圈荡开（两层错开，像接连滴了两滴） */
.fx-wave .wv { position: absolute; inset: 0; pointer-events: none; }
.fx-wave .wv-ripple {
  background-image: repeating-radial-gradient(circle at 50% 76%,
    rgba(255, 255, 255, .78) 0 2px, rgba(150, 215, 255, .48) 2px 3.4px, rgba(255, 255, 255, 0) 3.4px 28px);
  transform-origin: 50% 76%;
  animation: fx-wv-ripple 7s ease-out infinite;
}
.fx-wave .wv-ripple::after {
  content: ''; position: absolute; inset: 0;
  background-image: repeating-radial-gradient(circle at 26% 90%,
    rgba(255, 255, 255, .58) 0 1.8px, rgba(150, 215, 255, .34) 1.8px 3px, rgba(255, 255, 255, 0) 3px 25px);
  transform-origin: 26% 90%;
  animation: fx-wv-ripple 9.5s ease-out infinite;
  animation-delay: -4.5s;
}
@keyframes fx-wv-ripple {
  0%   { transform: scale(.3); opacity: 0; }
  10%  { opacity: .72; }
  60%  { opacity: .34; }
  100% { transform: scale(1.55); opacity: 0; }
}
/* 气泡：从水底一颗颗飘上去，到顶就淡出（background-position 位移是 tile 的整数倍） */
.fx-wave .wv-bubble {
  background-image:
    radial-gradient(circle, rgba(255, 255, 255, .9) 0 1.6px, rgba(255, 255, 255, .28) 1.6px 2.3px, transparent 2.7px),
    radial-gradient(circle, rgba(214, 244, 255, .72) 0 1.1px, transparent 1.8px);
  background-size: 54px 74px, 38px 52px;
  background-position: 8px 40px, 26px 18px;
  animation: fx-wv-bubble 10s linear infinite;
}
@keyframes fx-wv-bubble {
  from { background-position: 8px 40px, 26px 18px; }
  to   { background-position: 8px -108px, 26px -138px; }
}
/* 水光扫过：明亮的斜向流光，像阳光落在水面上 */
.fx-wave::after {
  background: linear-gradient(108deg, transparent 36%, rgba(255, 255, 255, .48) 45%, rgba(196, 240, 255, .36) 51%, transparent 61%);
  background-size: 260% 260%;
  animation: fx-water-sheen 6.8s ease-in-out infinite;
  opacity: 0;
}
@keyframes fx-water-sheen {
  0%, 100% { background-position: 120% 0; opacity: 0; }
  26%      { opacity: .7; }
  62%      { background-position: -40% 0; opacity: 0; }
}
/* 电：电光点闪烁 + 一道斜向电流扫过 */
.fx-spark::before {
  background-image:
    radial-gradient(circle, #fff 0, #fff 1.8px, rgba(255, 241, 118, .9) 2.4px, transparent 3.2px),
    radial-gradient(circle, #fffde7 0, #fffde7 1.2px, transparent 2px);
  background-size: 44px 58px, 30px 40px;
  background-position: 0 0, 14px 18px;
  animation: fx-spark-drift 3.6s linear infinite, fx-blit 1.1s steps(2, end) infinite;
}
@keyframes fx-spark-drift {
  from { background-position: 0 0, 14px 18px; }
  to   { background-position: 0 -174px, 14px -160px; }
}
@keyframes fx-blit { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }
.fx-spark::after {
  background: linear-gradient(118deg, transparent 38%, rgba(255, 255, 255, .85) 47%, rgba(255, 244, 150, .55) 51%, transparent 58%);
  background-size: 260% 260%;
  animation: fx-zap 2.8s ease-in-out infinite;
}
@keyframes fx-zap {
  0%, 62%, 100% { background-position: 130% 0; opacity: 0; }
  68%           { opacity: 1; }
  86%           { background-position: -30% 0; opacity: 0; }
}
/* 草 / 虫：叶片缓缓飘落 */
.fx-leaf::before {
  background-image:
    radial-gradient(ellipse 3.2px 6px at center, rgba(120, 200, 80, .95), transparent 72%),
    radial-gradient(ellipse 2.4px 4.6px at center, rgba(184, 230, 128, .9), transparent 72%),
    radial-gradient(ellipse 2px 4px at center, rgba(90, 160, 60, .75), transparent 72%);
  background-size: 62px 84px, 46px 62px, 78px 104px;
  background-position: 0 0, 22px 30px, 40px 16px;
  animation: fx-leaf-fall 6s linear infinite;
  opacity: .85;
}
@keyframes fx-leaf-fall {
  from { background-position: 0 0, 22px 30px, 40px 16px; }
  to   { background-position: 0 168px, 22px 186px, 40px 208px; }
}
.fx-leaf::after {
  background: radial-gradient(circle at 50% 100%, rgba(120, 200, 80, .18), transparent 62%);
  animation: fx-breathe 5s ease-in-out infinite;
}
/* 冰：雪花慢慢落 */
.fx-snow::before {
  background-image:
    radial-gradient(circle, rgba(255, 255, 255, .95) 0, rgba(255, 255, 255, .95) 2.2px, transparent 2.8px),
    radial-gradient(circle, rgba(225, 245, 255, .85) 0, rgba(225, 245, 255, .85) 1.4px, transparent 2px);
  background-size: 52px 72px, 34px 48px;
  background-position: 0 0, 20px 26px;
  animation: fx-snow-fall 7.5s linear infinite;
  opacity: .9;
}
@keyframes fx-snow-fall {
  from { background-position: 0 0, 20px 26px; }
  to   { background-position: 0 216px, 20px 192px; }
}
.fx-snow::after {
  background: radial-gradient(circle at 50% 8%, rgba(200, 240, 255, .3), transparent 58%);
  animation: fx-breathe 4.6s ease-in-out infinite;
}
/* 毒：紫绿毒雾柔和弥漫 + 上升毒孢 + 底部毒气呼吸（不再是满屏一圈圈的毒泡）
   雾用百分比椭圆 + 低透明度、缓变停靠点，边缘不会露出一个个"圆饼"的轮廓 */
.fx-toxic::before {
  background-image:
    radial-gradient(circle, rgba(214, 132, 228, .82) 0 1.5px, transparent 2.4px),
    radial-gradient(60% 46% at 30% 30%, rgba(202, 120, 216, .34), rgba(198, 118, 212, .12) 52%, transparent 76%),
    radial-gradient(54% 40% at 72% 62%, rgba(126, 200, 108, .26), rgba(126, 200, 108, .09) 54%, transparent 76%),
    radial-gradient(48% 38% at 46% 78%, rgba(112, 42, 132, .3), transparent 76%);
  background-size: 46px 62px, 210px 170px, 180px 150px, 160px 140px;
  background-repeat: repeat;
  background-position: 18px 40px, 0 0, 90px 60px, 40px 100px;
  animation: fx-toxic-drift 15s linear infinite;
}
@keyframes fx-toxic-drift {
  from { background-position: 18px 40px, 0 0, 90px 60px, 40px 100px; }
  to   { background-position: 18px -84px, 0 -170px, 90px -90px, 40px -40px; }
}
.fx-toxic::after {
  background:
    radial-gradient(circle at 50% 106%, rgba(150, 60, 165, .46), transparent 62%),
    radial-gradient(circle at 50% 108%, rgba(110, 180, 70, .2), transparent 72%);
  animation: fx-breathe 4.6s ease-in-out infinite;
}
/* 超能 / 妖精 / 龙 / 幽灵：中心灵光呼吸 + 星点闪动 */
.fx-aura::before {
  background: radial-gradient(circle at 50% 52%, rgba(255, 255, 255, .5), rgba(205, 180, 255, .3) 38%, transparent 66%);
  animation: fx-breathe 3.2s ease-in-out infinite;
}
.fx-aura::after {
  background-image:
    radial-gradient(circle, rgba(255, 255, 255, .95) 0, rgba(255, 255, 255, .95) 1.8px, transparent 2.6px),
    radial-gradient(circle, rgba(240, 220, 255, .9) 0, rgba(240, 220, 255, .9) 1.2px, transparent 2px);
  background-size: 66px 66px, 44px 44px;
  background-position: 0 0, 26px 20px;
  animation: fx-aura-drift 8s linear infinite, fx-blit 2.4s ease-in-out infinite;
}
@keyframes fx-aura-drift {
  from { background-position: 0 0, 26px 20px; }
  to   { background-position: 0 -132px, 26px -132px; }
}
/* 岩石 / 地面 / 钢 / 格斗：细碎尘土横向飘 */
.fx-dust::before {
  background-image:
    radial-gradient(circle, rgba(180, 160, 120, .8) 0, rgba(180, 160, 120, .8) 1.8px, transparent 2.6px),
    radial-gradient(circle, rgba(140, 120, 90, .65) 0, rgba(140, 120, 90, .65) 1.2px, transparent 2px);
  background-size: 58px 46px, 38px 32px;
  background-position: 0 0, 18px 14px;
  animation: fx-dust-drift 6.5s linear infinite;
  opacity: .8;
}
@keyframes fx-dust-drift {
  from { background-position: 0 0, 18px 14px; }
  to   { background-position: 116px -46px, 76px -32px; }
}
.fx-dust::after {
  background: linear-gradient(0deg, rgba(150, 130, 90, .18), transparent 55%);
  animation: fx-breathe 5.4s ease-in-out infinite;
}
/* 飞行 / 一般：气流斜着掠过 */
.fx-wind::before {
  background-image:
    repeating-linear-gradient(102deg, transparent 0 14px, rgba(255, 255, 255, .55) 14px 16px, transparent 16px 34px),
    repeating-linear-gradient(96deg, transparent 0 26px, rgba(255, 255, 255, .3) 26px 27px, transparent 27px 52px);
  background-size: 120px 84px, 160px 120px;
  background-position: 0 0, 40px 20px;
  animation: fx-wind-slide 3.6s linear infinite;
  opacity: .7;
}
@keyframes fx-wind-slide {
  from { background-position: 0 0, 40px 20px; }
  to   { background-position: 120px -84px, 160px -120px; }
}
.fx-wind::after {
  background: linear-gradient(100deg, transparent 40%, rgba(255, 255, 255, .25) 50%, transparent 60%);
  animation: fx-breathe 4.2s ease-in-out infinite;
}
.ptcg-skill {
  margin-top: 10px; background: rgba(255,255,255,.75); border-radius: 12px; padding: 10px 12px;
}
.ptcg-skill b { display: flex; align-items: center; justify-content: space-between; font-size: 15px; }
.ptcg-move { color: #fff; padding: 2px 10px; border-radius: 8px; }
.ptcg-skill em { font-style: normal; font-weight: 900; font-size: 17px; color: #263238; }
.ptcg-skill p { font-size: 12px; color: #546e7a; margin-top: 5px; line-height: 1.4; }

/* ---------- 招式区（4 个招式，点一行展开说明） ---------- */
.ptcg-moves {
  margin-top: 10px; background: rgba(255, 255, 255, .8);
  border-radius: 12px; padding: 8px 10px 6px;
}
.pmv-head { display: flex; align-items: baseline; gap: 6px; font-size: 12px; font-weight: 900; color: #37474f; }
.pmv-head small { font-size: 10px; font-weight: 500; color: #90a4ae; }
.pmv {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center; gap: 6px; padding: 5px 2px; cursor: pointer;
  border-top: 1px dashed rgba(0, 0, 0, .07); transition: background .12s;
}
.pmv:active { background: rgba(255, 255, 255, .7); }
.pmv.open { background: rgba(255, 255, 255, .7); }
.pmv-t {
  font-size: 10px; font-weight: 800; color: #fff; padding: 1px 6px;
  border-radius: 6px; white-space: nowrap; box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}
.pmv-n { font-size: 13px; font-weight: 800; color: #263238; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pmv-p { font-style: normal; font-weight: 900; font-size: 13px; color: #37474f; min-width: 24px; text-align: right; }
.pmv-p.none { color: #b0bec5; }
.pmv-c { font-size: 10px; font-weight: 700; color: #78909c; background: #eceff1; border-radius: 6px; padding: 1px 5px; white-space: nowrap; }
.pmv-c.special { color: #1565c0; background: #e3f2fd; }
.pmv-c.status { color: #6a1b9a; background: #f3e5f5; }
.pmv-d { display: none; grid-column: 1 / -1; margin: 2px 0 3px; font-size: 11px; line-height: 1.6; color: #546e7a; }
.pmv.open .pmv-d { display: block; }
.pmv.locked { cursor: default; opacity: .6; }
/* 未收集的剪影卡 */
.ptcg-missing .ptcg-art img { filter: brightness(0) opacity(.42); }
.ptcg-missing .ptcg-name { color: #eceff1; }
.ptcg-missing .ptcg-type { background: #78909c; }
.ptcg-foot { margin-top: 10px; color: #263238; }
.ptcg-caught { font-size: 9.5px; color: #a0a4a8; display: flex; align-items: center; gap: 3px; margin-bottom: 2px; }
.ptcg-caught .ball-ico { display: inline-block; width: 10px; height: 10px; }
.ptcg-caught .ball-ico svg { display: block; width: 100%; height: 100%; }
.ptcg-exprow { font-size: 11px; font-weight: 700; margin-bottom: 4px; }
.ptcg-chain { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.ptcg-chain span {
  display: inline-flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 700;
  padding: 3px 8px; border-radius: 999px; background: rgba(255,255,255,.6);
}
.ptcg-chain span.cur { background: #ffd54f; box-shadow: 0 2px 6px rgba(255,193,7,.5); }
.ptcg-chain img { width: 22px; height: 22px; image-rendering: pixelated; }
.ptcg-chain i { font-style: normal; font-size: 12px; }
/* 进化链每个形态可点开自己的详情 */
.ptcg-chain span.tap { cursor: pointer; transition: transform .12s, box-shadow .12s; }
.ptcg-chain span.tap:hover, .ptcg-chain span.tap:active { transform: translateY(-1px); box-shadow: 0 3px 8px rgba(0, 0, 0, .16); }
.chain-tip { margin-top: 6px; text-align: center; font-size: 10px; color: #90a4ae; }
/* 分支进化（伊布）：选进化形态 */
.evo-pick { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 12px; }
.evo-pick-item {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  border: 1px solid #e6ebf2; background: #fff; border-radius: 14px; padding: 8px 4px 10px;
  cursor: pointer; font-family: inherit; transition: transform .12s, box-shadow .12s;
}
.evo-pick-item img { width: 54px; height: 54px; object-fit: contain; }
.evo-pick-item b { font-size: 13px; color: #263238; }
.evo-pick-item small { font-size: 11px; font-weight: 800; }
.evo-pick-item:active { transform: scale(.96); box-shadow: 0 3px 10px rgba(0, 0, 0, .12); }
.ptcg-evo { margin-top: 8px; text-align: center; font-size: 12px; font-weight: 800; color: #6a5c1d; }
.ptcg-evo.ok { color: #e65100; animation: evo-pulse .9s infinite; }
@keyframes evo-pulse { 50% { transform: scale(1.08); color: #ff8f00; } }
.ptcg-btns { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-top: 12px; }
.ptcg-btns button {
  border: 0; cursor: pointer; border-radius: 999px; padding: 10px 4px;
  font-size: 12px; font-weight: 800; color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: clip;
  min-width: 0; letter-spacing: -.3px;
}
@media (max-width: 360px) { .ptcg-btns button { font-size: 11px; padding: 10px 2px; } }
.ptcg-btns .btn-lead { background: linear-gradient(135deg, #ef5350, #e53935); box-shadow: 0 3px 0 #b71c1c; }
.ptcg-btns .btn-feed { background: linear-gradient(135deg, #7e57c2, #5e35b1); box-shadow: 0 3px 0 #4527a0; }
.ptcg-btns .btn-evo { background: linear-gradient(135deg, #ffb300, #fb8c00); box-shadow: 0 3px 0 #e65100; }
.ptcg-btns .btn-evo:disabled { filter: grayscale(1); opacity: .5; box-shadow: none; }
.ptcg-btns .btn-close { background: rgba(0,0,0,.4); }
.ptcg-btns .btn-lead:disabled { filter: grayscale(1); opacity: .5; box-shadow: none; }
/* 只读「图鉴形态」详情：两个按钮 */
.ptcg-btns.dex-btns { grid-template-columns: repeat(2, 1fr); }
.ptcg-btns.dex-btns .btn-owned { background: linear-gradient(135deg, #4fc3f7, #0288d1); box-shadow: 0 3px 0 #01579b; }

/* ---------- 可选任务 ---------- */
.task-card.optional { border: 2px dashed #ffd54f; }
.task-card.optional .emoji { background: #fff8e1; }

/* ---------- 本周任务 · 子任务列表 ---------- */
.weekly-parent { border-bottom: 2px dashed #ffe0b2; border-radius: var(--radius) var(--radius) 0 0; margin-bottom: 0; }
.child-list { margin: 8px 0 14px; padding: 0 16px; display: flex; flex-direction: column; gap: 6px; }
.child-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  border: 2px solid #ffe0b2; background: #fff8f0; border-radius: 12px;
  padding: 9px 12px; font-size: 14px; cursor: pointer;
  font-family: inherit; color: var(--ink); text-align: left;
}
.child-item:active { transform: scale(.98); }
.child-item.done { border-color: #a5d6a7; background: #f1f8e9; opacity: .7; }
.child-item .child-check { font-size: 16px; flex: none; }
.child-item .child-name { flex: 1; font-weight: 700; min-width: 0; }
.child-item .child-pct { font-weight: 800; color: #fb8c00; font-size: 12px; background: #fff3e0; border-radius: 999px; padding: 2px 8px; flex: none; }

/* ---------- 朋友圈成就卡 ---------- */
#share-wrap { position: fixed; top: 0; left: -9999px; width: 640px; }
.share-card {
  width: 640px; padding: 40px; text-align: center;
  background: linear-gradient(160deg, var(--bg1), var(--bg2));
  border: 6px solid var(--tc, #a8a878); border-radius: 32px;
}
.share-head { font-size: 40px; font-weight: 900; color: #fff; text-shadow: 0 3px 0 rgba(0,0,0,.3); }
.share-pm img { width: 220px; height: 220px; object-fit: contain; margin: 20px 0 8px; filter: drop-shadow(0 6px 18px rgba(0,0,0,.3)); }
.share-pm-name { font-size: 34px; font-weight: 900; color: #fff; text-shadow: 0 2px 0 rgba(0,0,0,.35); }
.share-pm-name span { display: block; font-size: 20px; font-weight: 800; margin-top: 4px; opacity: .9; }
.share-stats { display: flex; gap: 12px; margin-top: 28px; }
.share-stats div { flex: 1; background: rgba(255,255,255,.82); border-radius: 20px; padding: 18px 8px; }
.share-stats b { display: block; font-size: 34px; color: var(--ink); }
.share-stats span { font-size: 14px; color: #546e7a; }
.share-date { margin-top: 26px; font-size: 18px; font-weight: 800; color: rgba(255,255,255,.95); }

.overlay.share-view { background: rgba(15,15,30,.94); }
.share-img { max-width: min(420px, 88vw); border-radius: 18px; box-shadow: 0 12px 50px rgba(0,0,0,.6); }
.share-tip { margin-top: 14px; font-size: 14px; color: #ffd54f; font-weight: 700; }
/* 生成中：先给反馈，手机上 html2canvas 要一两秒 */
.share-loading { display: flex; flex-direction: column; align-items: center; gap: 16px; font-size: 14px; font-weight: 700; color: #fff; }
.share-spin {
  width: 44px; height: 44px; border-radius: 50%;
  border: 4px solid rgba(255, 255, 255, .22); border-top-color: #ffd54f;
  animation: share-spin .8s linear infinite;
}
@keyframes share-spin { to { transform: rotate(360deg); } }

@media (min-width: 640px) {
  /* 桌面端同样要留出底部导航/fab 的高度，不能缩小，否则滚到底会被挡住 */
  .page { padding-bottom: calc(120px + env(safe-area-inset-bottom)); }
  .tabbar { max-width: 720px; left: 50%; transform: translateX(-50%); border-radius: 20px 20px 0 0; }
}

/* 长期任务倒计时徽章（不刺眼：蓝 / 琥珀 / 紫，替换原来的棕 + 红） */
.dl-badge {
  display: inline-block; font-size: 11px; font-weight: 700;
  color: #1565c0; background: linear-gradient(135deg, #e3f2fd, #d3ecfb);
  border: 1px solid #b3e0f7; border-radius: 999px; padding: 2px 8px; margin-left: 6px;
  vertical-align: middle; white-space: nowrap;
}
.dl-badge.urgent {
  color: #b26a00; background: linear-gradient(135deg, #fff8e1, #ffefc2);
  border-color: #ffe0a3;
}
.dl-badge.overdue {
  color: #5e35b1; background: linear-gradient(135deg, #ede7f6, #e4dbf7);
  border-color: #d3c6f0;
}

/* 必做/选做标记（低调浅色） */
.req-tag {
  display: inline-block; font-size: 11px; font-weight: 700;
  background: #ffe3e3; color: #c62828; border-radius: 999px; padding: 2px 8px;
  margin-left: 6px; vertical-align: middle; white-space: nowrap;
}
.req-tag.opt { background: #e8f5e9; color: #2e7d32; }
/* 家长小提示 */
.task-hint { font-size: 12px; color: #8d6e63; margin-top: 2px; }
/* 子任务卡稍紧凑 */
.task-card.child-card { padding: 8px 12px; }

/* 多日任务超期扣分提示 */
.dl-penalty { margin-top: 6px; font-size: 11px; color: #b26a00; }

/* 手机窄屏：任务卡紧凑，名称完整显示（不再剩单字宽） */
@media (max-width: 480px) {
  .task-card { gap: 8px; padding: 12px 12px; }
  .task-card .emoji { width: 38px; height: 38px; font-size: 20px; border-radius: 10px; }
  .task-card .info b { font-size: 15px; white-space: normal; line-height: 1.35; }
  .task-card .pts { font-size: 14px; }
  .btn-done { padding: 9px 14px; font-size: 14px; }
}

/* 演示模式标记 */
.demo-tag {
  font-size: 11px; font-weight: 700; color: #fff; background: #7e57c2;
  display: inline-block; border-radius: 8px; padding: 2px 8px; margin-bottom: 4px;
}
/* 家长中心顶部：牌子跟在标题后面一行，不挤占标题 */
.topbar .title .demo-tag {
  margin: 0 0 0 8px; vertical-align: middle;
  font-style: normal; font-size: 11px; letter-spacing: .3px;
  box-shadow: 0 2px 6px rgba(126, 87, 194, .35);
}
/* 类别下拉的「自定义类别」输入框：独占一行 */
.input-row .cat-custom { flex: 1 1 100%; }
/* 积分到账提示条 */
.pts-notice {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin: 8px 12px 0; padding: 8px 12px; background: #e3f2fd; color: #1565c0;
  border-radius: 12px; font-size: 13px; font-weight: 600;
}
/* 当天叮嘱卡片（和任务列表一样的等宽圆角风格） */
.note-card {
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 12px 16px; margin-bottom: 12px; color: #ef6c00;
  display: flex; flex-direction: column; gap: 6px;
}
.note-card .note-head { font-size: 12px; font-weight: 800; letter-spacing: .5px; opacity: .72; }
.note-card .note-lines { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.note-card .note-lines li { display: flex; align-items: flex-start; gap: 9px; font-size: 15px; font-weight: 600; }
.note-card .note-ico { flex: 0 0 19px; width: 19px; height: 19px; margin-top: 2px; }
.note-card .note-ico svg { width: 100%; height: 100%; display: block; }
.note-card .note-line { flex: 1; min-width: 0; line-height: 1.5; word-break: break-word; }

/* ---------- 孩子端「家长消息」卡（任务页顶端，点一下确认） ---------- */
.notice-stack {
  display: flex; flex-direction: column; gap: 10px; margin: 0 0 12px;
  animation: notice-in .35s cubic-bezier(.2, 1.4, .4, 1) both;
}
@keyframes notice-in { from { opacity: 0; transform: translateY(-10px); } }
.notice-head {
  display: flex; align-items: baseline; gap: 8px; padding: 0 4px;
  font-size: 13px; font-weight: 800; color: #fff;
  text-shadow: 0 1px 4px rgba(0, 0, 0, .18);
}
.notice-head small { font-weight: 600; opacity: .9; font-size: 11px; }
.notice-card {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  background: var(--card); border-radius: 16px; box-shadow: var(--shadow);
  padding: 12px; border-left: 6px solid #90a4ae;
  transition: transform .15s ease;
}
.notice-card:active { transform: scale(.985); }
.notice-card.ball { border-left-color: #e53935; background: linear-gradient(180deg, #fff, #fff6f6); }
.notice-card.minus { border-left-color: #8e24aa; background: linear-gradient(180deg, #fff, #faf5ff); }
.notice-card.points { border-left-color: #43a047; background: linear-gradient(180deg, #fff, #f4fbf4); }
.notice-card.bonus { border-left-color: #fb8c00; background: linear-gradient(180deg, #fff, #fffaf2); }
.notice-ic { font-size: 22px; line-height: 1; flex: none; }
.notice-body { flex: 1; min-width: 0; }
.notice-title { font-size: 14px; font-weight: 800; line-height: 1.35; }
.notice-meta { font-size: 11px; color: var(--ink-soft); margin-top: 2px; }
.notice-ok {
  flex: none; font-size: 12px; font-weight: 800; color: #fff; white-space: nowrap;
  background: linear-gradient(135deg, #66bb6a, #43a047); box-shadow: 0 3px 0 #2e7d32;
  border-radius: 999px; padding: 7px 12px;
}
.notice-card.ball .notice-ok { background: linear-gradient(135deg, #ef5350, #e53935); box-shadow: 0 3px 0 #b71c1c; }
.notice-card.minus .notice-ok { background: linear-gradient(135deg, #ab47bc, #8e24aa); box-shadow: 0 3px 0 #6a1b9a; }
.notice-card.bonus .notice-ok { background: linear-gradient(135deg, #ffa726, #fb8c00); box-shadow: 0 3px 0 #e65100; }
.notice-all {
  align-self: center; border: 0; cursor: pointer;
  background: rgba(255, 255, 255, .88); color: var(--ink-soft);
  font-size: 12px; font-weight: 700; border-radius: 999px;
  padding: 7px 16px; box-shadow: var(--shadow);
}
/* 底部「任务」页签的未读角标 */
.tabbar button { position: relative; }
.tab-dot {
  position: absolute; top: 2px; left: 50%; margin-left: 2px;
  min-width: 16px; height: 16px; padding: 0 4px;
  display: inline-flex; align-items: center; justify-content: center;
  background: #ee4444; color: #fff; font-size: 10px; font-style: normal; font-weight: 800;
  border-radius: 999px; box-shadow: 0 2px 6px rgba(238, 68, 68, .45);
}

/* ---------- 异常提示条（固定顶部，可展开/复制，方便下次排查） ---------- */
#err-banner {
  position: fixed; left: 50%; top: 8px; transform: translateX(-50%);
  z-index: 999; width: calc(100% - 24px); max-width: 560px;
  background: #fff3f3; border: 1px solid #ef9a9a; border-radius: 14px;
  box-shadow: 0 8px 24px rgba(198, 40, 40, .22);
  padding: 10px 12px; animation: err-in .25s ease both;
}
@keyframes err-in { from { opacity: 0; transform: translate(-50%, -12px); } }
#err-banner .err-row { display: flex; align-items: center; gap: 8px; }
#err-banner .err-ic { font-size: 18px; flex: none; }
#err-banner .err-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
#err-banner .err-main b { font-size: 12px; color: #c62828; }
#err-banner .err-main span {
  font-size: 12px; color: #5d4037;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#err-banner .err-btn {
  flex: none; border: 0; cursor: pointer; font-size: 11px; font-weight: 800;
  padding: 6px 10px; border-radius: 999px; color: #fff;
  background: #c62828; box-shadow: 0 2px 0 #8e0000;
}
#err-banner .err-btn.ghost { background: #fff; color: #c62828; box-shadow: inset 0 0 0 1px #ef9a9a; }
#err-banner .err-stack {
  margin-top: 8px; max-height: 180px; overflow: auto;
  font-size: 11px; line-height: 1.5; color: #4e342e;
  background: #fff; border-radius: 8px; padding: 8px;
  white-space: pre-wrap; word-break: break-all;
}
/* 家长端错误日志列表 */
.err-item { background: #fafafa; border-radius: 10px; padding: 8px 10px; margin-bottom: 8px; font-size: 12px; }
.err-item b { color: #c62828; font-size: 12px; }
.err-item span { color: #90a4ae; margin-left: 6px; font-size: 11px; }
.err-item p { margin: 4px 0 0; color: #37474f; word-break: break-all; }
.err-item small { color: #78909c; word-break: break-all; display: block; margin-top: 2px; }
.err-item pre { font-size: 11px; white-space: pre-wrap; word-break: break-all; color: #546e7a; margin-top: 4px; }
.err-item summary { cursor: pointer; color: #607d8b; margin-top: 4px; font-size: 11px; }

/* ---------- iOS 14 及更早 Safari 兼容 ----------
   aspect-ratio 在 Safari 15 / iOS 15 才支持，旧版 Safari 不识别会直接丢弃，
   导致宝可梦图鉴格子、小卡牌框、详情卡大图高度塌陷、图片被裁、卡片布局乱。
   这里用经典的 padding-bottom 撑高技巧给它们补上正方形高度；
   @supports not 只有真正不支持 aspect-ratio 的浏览器才命中，新浏览器不受影响。
   注意：内部原本 absolute 定位的元素（属性徽章/特效层）保持原样，只有主图改 absolute 填满。 */
@supports not (aspect-ratio: 1 / 1) {
  /* 图鉴格子：保持 flex 居中，补最小高度避免图片被裁/格子塌成一条 */
  .dex-cell { min-height: 64px; }
  /* 小卡牌图框：padding-bottom 撑正方形，图片铺满 */
  .mini-frame { height: 0; padding-bottom: 100%; }
  .mini-frame > img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
  /* 详情卡大图：padding-bottom 撑正方形，图片铺满（fx/type/glitter 仍是 absolute，盖在上面） */
  .ptcg-art { height: 0; padding-bottom: 100%; }
  .ptcg-art > img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
  /* 场景卡：整张中文卡面按自身比例撑高，不能套正方形兜底（否则底下多出 100% 空白 + 图绝对定位塌陷） */
  .ptcg.scene-mode .ptcg-art { height: auto; padding-bottom: 0; }
  .ptcg.scene-mode .ptcg-art > img { position: static; height: auto; }
  /* 日历格子 */
  .cal-day { min-height: 40px; }
}

/* inset 简写在 Safari 14.0-14.4 / iOS 14.0-14.4 不支持，全屏遮罩会失去铺满效果 */
@supports not (inset: 0) {
  .modal-mask, .overlay, .shiny-bg, .shiny-rain, .ptcg-glitter, .ptcg-fx {
    top: 0; left: 0; right: 0; bottom: 0;
  }
}

/* backdrop-filter 在 Safari 需要 -webkit- 前缀才生效（旧版 Safari 认带前缀的） */
.modal-mask, .overlay { -webkit-backdrop-filter: blur(4px); }
