@font-face {
  font-family: "VT323";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/vt323.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/ibm-plex-mono-400.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/ibm-plex-mono-500.woff2") format("woff2");
}

:root {
  --bg: #07070C;
  --paper: #ECEAF5;
  --amber: #FFB36B;
  --dim: rgba(236, 234, 245, 0.56);
  --faint: rgba(236, 234, 245, 0.18);
  --line: rgba(236, 234, 245, 0.1);
  --glass: rgba(11, 11, 18, 0.78);
  --mono: "IBM Plex Mono", "SF Mono", Menlo, "PingFang SC", monospace;
  --vt: "VT323", "SF Mono", Menlo, monospace;
  --cjk: "PingFang SC", "Hiragino Sans GB", "Noto Sans SC", "Microsoft YaHei", sans-serif;

  /* 类别颜色：霓虹灯管那样饱和、亮，每张卡片按自己内容的类别取一种 */
  --c-class: #5C9DFF;
  --c-eat: #FFD447;
  --c-sleep: #9B7CFF;
  --c-office: #2BE3A0;
  --c-research: #7CF26B;
  --c-dev: #2FD8FF;
  --c-game: #FF4D6D;
  --c-out: #FF8A3D;
  --c-custom: #E8C27A;
  --c-video: #FF4FD8;
  --c-browse: #A9B4C8;
  --c-phone: #C77DFF;
  --c-music: #FFB020;
  --c-away: rgba(236, 234, 245, 0.35);
  --c-offline: rgba(236, 234, 245, 0.2);
}
/* 历史视图的界面配色跟立绘一样走粉色系（类别颜色照旧，和图例对得上）：
   各面板一种粉、提示文字和焦点框、背景里跑的光都从这几种里取 */
:root {
  --pk-hot: #FF4FD8;
  --pk-rose: #FF6B9D;
  --pk-orchid: #D27BFF;
  --pk-blush: #FFB8DE;
}
html[data-view="history"] { --amber: var(--pk-hot); }
/* 此刻视图同理走蓝色系（跟蓝色立绘配）：卡片颜色由 app.js 的 cardHue 映射到这几种蓝，
   摸鱼、离线提示和背景里的光也用蓝色系；时间线色块和图例照旧用类别颜色 */
:root {
  --bl-cyan: #2FD8FF;
  --bl-blue: #5C9DFF;
  --bl-indigo: #7F8CFF;
  --bl-violet: #A07CFF;
  --bl-ice: #9FDFFF;
}
html[data-view="now"] { --amber: var(--bl-ice); }

* { box-sizing: border-box; }

html, body { margin: 0; }
/* 不显示页面右侧的滚动条（照样能滚动） */
html { scrollbar-width: none; }
html::-webkit-scrollbar { display: none; }

body {
  background: var(--bg);
  color: var(--paper);
  font-family: var(--mono), var(--cjk);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}
/* 画布不可用时的静态网格（和 bg.js 的网格同间距）；平时被 bg.js 的画布盖住 */
body {
  background:
    linear-gradient(rgba(236, 234, 245, 0.035) 1px, transparent 1px) 0 0 / 56px 56px fixed,
    linear-gradient(90deg, rgba(236, 234, 245, 0.035) 1px, transparent 1px) 0 0 / 56px 56px fixed,
    var(--bg);
}
canvas.bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  pointer-events: none;
  animation: bg-in 1.6s ease-out;
}
@keyframes bg-in { from { opacity: 0; } }

/* 扫描线 */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0) 0 2px, rgba(0, 0, 0, 0.18) 2px 3px);
  mix-blend-mode: multiply;
}

a { color: inherit; }

.wrap {
  max-width: 880px; /* 三个页面同宽 */
  margin: 0 auto;
  padding: max(24px, env(safe-area-inset-top)) 16px 48px;
}

.top {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--vt);
  font-size: 22px;
  color: var(--dim);
}
/* 顶部此刻 / 历史的切换 */
.tabs {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--glass);
}
.tabs a {
  padding: 4px 14px;
  border-radius: 999px;
  font: 500 14px/1.4 var(--cjk);
  color: var(--dim);
  text-decoration: none;
  transition: color 0.2s, background 0.2s;
}
/* 两个页面各一种霓虹色，当前页亮起来 */
.tabs a:nth-child(1) { --hue: var(--c-dev); }
.tabs a:nth-child(2) { --hue: var(--c-video); }
.tabs a:hover { color: var(--hue); }
.tabs a[aria-current="page"] {
  color: var(--hue);
  background: color-mix(in srgb, var(--hue) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--hue) 70%, transparent), 0 0 16px -2px color-mix(in srgb, var(--hue) 55%, transparent);
  text-shadow: 0 0 10px color-mix(in srgb, var(--hue) 70%, transparent);
}
.top .logout { margin-left: auto; font: 13px var(--cjk); text-decoration: none; }
.top .logout:hover { color: var(--paper); }
.air {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 18px;
  letter-spacing: 0.08em;
}
.air i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--faint);
}
.air[data-state="live"] { color: var(--paper); }
.air[data-state="live"] i { background: #FF4B3E; box-shadow: 0 0 10px #FF4B3E; animation: blink 2.4s infinite; }
.air[data-state="down"] i { background: var(--faint); }
@keyframes blink { 50% { opacity: 0.35; } }

/* 主状态：大字 + 背后若隐若现的封面 */
.hero {
  position: relative;
  isolation: isolate;
  margin-top: 36px;
  padding: 30px 28px 28px;
  border: 1px solid color-mix(in srgb, var(--hue, var(--amber)) 22%, var(--line));
  border-radius: 22px;
  background:
    var(--spot),
    radial-gradient(120% 100% at 0% 0%, color-mix(in srgb, var(--hue, var(--amber)) 14%, transparent), transparent 65%),
    var(--glass);
  box-shadow: 0 20px 50px -30px rgba(0, 0, 0, 0.8), inset 0 1px 0 rgba(236, 234, 245, 0.06);
  overflow: hidden;
  transition: border-color 0.8s, box-shadow 0.8s;
}
.hero::before {
  content: "";
  position: absolute;
  inset: -40px;
  z-index: -1;
  background: var(--art, none) center / cover no-repeat;
  filter: blur(48px) saturate(1.3);
  opacity: 0.22;
  transition: opacity 0.8s;
}
.hero:not([style*="--art"])::before { opacity: 0; }
.kicker {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin: 0;
  font-family: var(--vt);
  font-size: 22px;
  letter-spacing: 0.12em;
  color: var(--hue, var(--dim));
}
.kicker::before {
  content: "";
  align-self: center;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 12px currentColor;
}
.kicker .clock { margin-left: auto; color: var(--dim); font-size: 20px; letter-spacing: 0.06em; }
.main {
  margin: 10px 0 8px;
  font-family: var(--cjk);
  font-weight: 600;
  font-size: clamp(32px, 7.4vw, 56px);
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--hue, var(--paper));
  text-shadow: 0 0 32px color-mix(in srgb, var(--hue, var(--amber)) 35%, transparent);
  overflow-wrap: anywhere;
  /* 超长课名、歌名：最多两行，悬停看全文 */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.main.long { font-size: clamp(26px, 5.4vw, 40px); }
.app-icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  margin-inline-end: 0.28em;
  vertical-align: -0.12em;
  border-radius: 23%;
  object-fit: cover;
}
.app-icon[hidden] { display: none; }
.hero-card:empty { display: none; }
.hero-card .card { margin-top: 20px; }
.meta { margin: 0; color: var(--dim); }
.meta .slack { color: var(--amber); white-space: nowrap; }
.notice { margin: 14px 0 0; color: var(--amber); }

/* 音乐 / 视频 / 游戏 / 网页卡片 */
.card {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 14px;
  align-items: center;
  margin-top: 14px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--spot, none), rgba(236, 234, 245, 0.03);
  text-decoration: none;
  position: relative;
}
.card.wide { grid-template-columns: 112px 1fr; }
.card .cover {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 8px;
  background: var(--faint) center / cover no-repeat;
}
.card.wide .cover { aspect-ratio: 16 / 9; }
/* 音乐来源：封面右下角的播放器图标 */
.card .cover { position: relative; }
.card .cover .player {
  position: absolute;
  right: -6px;
  bottom: -6px;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  box-shadow: 0 0 0 2px var(--bg, #111);
}
.card .cover .player.aimp { border-radius: 50%; } /* AIMP 标志是圆的 */
/* 网页：不画框，一行“小图标 标题 · 域名” */
.card.web {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding: 0;
  border: 0;
  background: none;
  min-width: 0;
}
.card.web .cover { flex: none; width: 16px; height: 16px; aspect-ratio: auto; border-radius: 3px; background: center / contain no-repeat; }
.card.web .cover:not([style*="background-image"]) { display: none; }
.card.web .body { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.card.web .t { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 400; font-size: 14px; color: var(--paper); }
.card.web .s { flex: none; font-size: 12px; }
a.card.web:hover .t { text-decoration: underline; text-underline-offset: 3px; }
.card .body { min-width: 0; }
.card .t {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  font-family: var(--cjk);
  font-weight: 600;
  overflow-wrap: anywhere;
}
.card .s { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dim); font-size: 13px; }
.progress { height: 3px; margin-top: 8px; border-radius: 2px; background: var(--faint); overflow: hidden; }
.progress i { display: block; height: 100%; width: 0; background: var(--hue, var(--amber)); }
.card .times {
  display: flex;
  justify-content: space-between;
  margin-top: 4px;
  color: var(--dim);
  font: 12px var(--mono);
  font-variant-numeric: tabular-nums;
}
/* 右上角：播放器 · 连续听了多久 */
.card.has-badge { position: relative; }
.card.has-badge .t { padding-right: var(--badge-w, 112px); }
.card .badge {
  position: absolute;
  top: 12px;
  right: 12px;
  color: var(--dim);
  font: 12px var(--mono), var(--cjk);
  white-space: nowrap;
}
@media (max-width: 480px) {
  /* 窄屏：标签单独一行，仍在右上角，不挤占歌名 */
  .card.has-badge .t { padding-right: 0; }
  .card .badge { position: static; grid-column: 1 / -1; grid-row: 1; justify-self: end; margin: -4px 0 -8px; }
}

/* 伴随状态：音乐、视频是大卡片（占满一行），其余是整齐的小卡片 */
.side { margin-top: 24px; }
.side[hidden] { display: none; }
.tiles {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 268px), 1fr));
  gap: 12px;
  margin: 0;
  padding: 0;
}
.tile { position: relative; min-width: 0; }
.tile.big { grid-column: 1 / -1; }
.tile.big .card {
  margin: 0;
  padding: 14px;
  border-radius: 16px;
  background: var(--spot), linear-gradient(135deg, color-mix(in srgb, var(--hue) 10%, transparent), transparent 55%), var(--glass);
  transition: border-color 0.2s;
}
.tile.big .card { grid-template-columns: 76px 1fr; }
.tile.big .card.wide { grid-template-columns: 136px 1fr; }
.tile.big a.card:hover { border-color: color-mix(in srgb, var(--hue) 45%, transparent); }
.tile > .in {
  position: relative;
  display: grid;
  grid-template-columns: 52px 1fr;
  gap: 12px;
  align-items: center;
  height: 100%;
  padding: 12px 14px 14px 12px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background:
    var(--spot),
    linear-gradient(135deg, color-mix(in srgb, var(--hue) 10%, transparent), transparent 55%),
    var(--glass);
  text-decoration: none;
  overflow: hidden;
  transition: border-color 0.2s;
}
a.in:hover { border-color: color-mix(in srgb, var(--hue) 45%, transparent); }
.tile .thumb {
  position: relative;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--hue) 14%, rgba(236, 234, 245, 0.04)) center / cover no-repeat;
  color: var(--hue);
  font: 30px/1 var(--vt);
}
.tile.wide .in { grid-template-columns: 84px 1fr; }
.tile.wide .thumb { width: 84px; height: 52px; }
.tile .thumb img.ic, .tile .thumb .app-icon { width: 100%; height: 100%; margin: 0; border-radius: 10px; object-fit: cover; }
.tile .thumb .player { position: absolute; right: -5px; bottom: -5px; width: 18px; height: 18px; border-radius: 5px; box-shadow: 0 0 0 2px #0C0C14; }
.tile .thumb .player.aimp { border-radius: 50%; }
.tile .info { min-width: 0; }
.tile .row { display: flex; align-items: baseline; gap: 8px; font-size: 12px; }
.tile .cat { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--hue); font-family: var(--cjk); }
.tile .time { margin-left: auto; flex: none; color: var(--dim); font-variant-numeric: tabular-nums; }
.tile .ttl {
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--cjk);
  font-weight: 600;
  font-size: 15px;
}
.tile .sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dim); font-size: 12px; }
.tile .prog { position: absolute; left: 0; bottom: 0; height: 2px; background: var(--hue); box-shadow: 0 0 8px var(--hue); }
.tile.paused .thumb { filter: grayscale(0.6) brightness(0.7); }

/* 今日时间线 */
.today {
  position: relative;
  margin-top: 24px;
  padding: 18px 20px 20px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--spot), var(--glass);
}
.today-head { display: flex; align-items: baseline; justify-content: space-between; }
.today h2 { margin: 0; font-family: var(--vt); font-weight: 400; font-size: 24px; letter-spacing: 0.08em; }
.today-head span { color: var(--dim); font-size: 13px; }
.bar {
  position: relative;
  height: 26px;
  margin-top: 10px;
  border-radius: 6px;
  background: rgba(236, 234, 245, 0.05);
  overflow: hidden;
}
.bar .blk { position: absolute; top: 0; bottom: 0; min-width: 1px; background: var(--hue); }
.bar .cursor { position: absolute; top: -2px; bottom: -2px; width: 2px; background: var(--paper); opacity: 0.7; z-index: 1; }
.today .bar {
  height: 34px;
  border-radius: 8px;
  /* 每两小时一条细线 */
  background:
    repeating-linear-gradient(to right, transparent 0 calc(100% / 12 - 1px), rgba(236, 234, 245, 0.06) calc(100% / 12 - 1px) calc(100% / 12)),
    rgba(236, 234, 245, 0.04);
}
.today .bar .blk { opacity: 0.88; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18); }
.today .bar .cursor { opacity: 1; box-shadow: 0 0 10px var(--paper); }
.ticks { display: flex; justify-content: space-between; margin-top: 4px; color: var(--dim); font-size: 11px; }
.totals { list-style: none; display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 16px 0 0; padding: 0; }
.totals li { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.totals li::before { content: ""; width: 9px; height: 9px; border-radius: 2px; background: var(--hue); }
.totals b { font-weight: 500; }
.totals span { color: var(--dim); }
.today .totals { gap: 8px; }
.today .totals li {
  padding: 3px 10px 3px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(236, 234, 245, 0.03);
}

@media (max-width: 480px) {
  .hero { padding: 24px 18px 20px; border-radius: 18px; }
  .today { padding: 16px 14px 18px; }
  .tiles { gap: 8px; }
  .tile > .in { grid-template-columns: 44px 1fr; gap: 10px; padding: 10px 12px 11px 10px; }
  .tile .thumb { width: 44px; height: 44px; font-size: 26px; }
  .tile.wide .in { grid-template-columns: 72px 1fr; }
  .tile.wide .thumb { width: 72px; height: 44px; }
  .tabs a { padding: 4px 11px; }
}

/* 霓虹卡片：每张卡片只用自己的 --hue —— 边框是一圈半透明灯管，顶边一道更亮的光（inset 阴影，跟着圆角弯），
   外面一层很淡的同色辉光（都写在下面悬停倾斜的 box-shadow 里），里面左上角带一点同色。
   背景从边框外沿开始铺（border-box）：默认从边框内侧铺，渐变会在半透明边框底下重复一份，圆角处接不上 */
.hero, .today, .panel, .tile > .in, .tile.big .card, .hero-card .card:not(.web), .stat {
  border-color: color-mix(in srgb, var(--hue, var(--amber)) 34%, transparent);
  background:
    var(--spot),
    linear-gradient(150deg, color-mix(in srgb, var(--hue, var(--amber)) 11%, transparent), transparent 50%),
    var(--glass);
  background-origin: border-box;
  background-repeat: no-repeat;
}
.today h2, .panel h2 { color: var(--hue, var(--paper)); text-shadow: 0 0 14px color-mix(in srgb, var(--hue, var(--amber)) 55%, transparent); }
.stat b { color: var(--hue); text-shadow: 0 0 12px color-mix(in srgb, var(--hue) 45%, transparent); }

/* 鼠标泛光（参照 personal_profile 的 spotlight）：鼠标所在的那张卡片（bg.js 加 data-lit）
   里面亮起一团柔光、边缘亮起一道高光，都跟着鼠标走（--spot-x / --spot-y 是相对卡片的坐标）；
   移开时在原处慢慢淡出。--lit 注册成数字才能做淡入淡出。
   颜色取卡片自己的 --hue（时间线、历史面板由 bg.js 按卡片内容算出） */
@property --lit { syntax: "<number>"; inherits: true; initial-value: 0; }
.hero, .today, .tile > .in, .tile.big .card, .hero-card .card:not(.web), .panel {
  --lit: 0;
  --spot: radial-gradient(380px circle at var(--spot-x, 50%) var(--spot-y, 50%),
    color-mix(in srgb, var(--hue, var(--amber)) calc(var(--lit) * 15%), transparent), transparent 62%);
  transition: --lit 0.45s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.2s;
}
:is(.hero, .today, .tile > .in, .tile.big .card, .hero-card .card:not(.web), .panel)[data-lit] { --lit: 1; }
.hero::after, .today::after, .tile > .in::after, .tile.big .card::after, .hero-card .card:not(.web)::after, .panel::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  padding: 1px;
  border-radius: inherit;
  background: radial-gradient(260px circle at var(--spot-x, 50%) var(--spot-y, 50%),
    color-mix(in srgb, var(--hue, var(--amber)) 60%, #fff 40%), transparent 68%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  pointer-events: none;
  opacity: calc(var(--lit) * 0.8);
}

/* 悬停倾斜（参照 personal_profile 的 data-tilt）：卡片跟着鼠标朝光源方向翻转、浮起，阴影加深；
   bg.js 给 data-lit 的卡片写 --tilt-x / --tilt-y（-1…1）。
   小卡片转得明显；音乐、视频长条和大面板（主状态、时间线、历史面板）很宽，同样的角度边缘会甩得太远，所以角度小一些。
   浮起、放大、阴影直接写在 [data-lit] 上，不跟着 --lit 逐帧重算：变形交给合成器（will-change），
   归位时不会因为每帧重算样式、重画大块阴影而卡顿 */
.tile > .in, .stat {
  --tilt-deg: 10deg;
  --lift: -6px;
  --grow: 1.025;
  --depth: 700px;
}
/* 音乐、视频的长条卡片：宽而矮，左右转一点点就甩得很远，角度和放大都收着 */
.tile.big .card, .hero-card .card:not(.web) {
  --tilt-deg: 3deg;
  --lift: -3px;
  --grow: 1.008;
  --depth: 1400px;
}
.hero, .today, .panel {
  --tilt-deg: 2.4deg;
  --lift: -4px;
  --grow: 1.006;
  --depth: 1600px;
}
.hero, .today, .panel, .tile > .in, .tile.big .card, .hero-card .card:not(.web), .stat {
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  transform: perspective(var(--depth))
    rotateX(calc(var(--tilt-x, 0) * var(--tilt-deg)))
    rotateY(calc(var(--tilt-y, 0) * var(--tilt-deg) * 1.2));
  translate: 0 0;
  scale: 1;
  box-shadow:
    0 12px 30px -22px rgba(0, 0, 0, 0.6),
    0 0 26px -12px color-mix(in srgb, var(--hue, var(--amber)) 60%, transparent),
    inset 0 1px 0 color-mix(in srgb, var(--hue, var(--amber)) 45%, transparent),
    inset 0 0 22px -14px color-mix(in srgb, var(--hue, var(--amber)) 70%, transparent);
  will-change: transform;
  transition:
    --lit 0.45s var(--ease),
    transform 0.5s var(--ease),
    translate 0.5s var(--ease),
    scale 0.5s var(--ease),
    box-shadow 0.5s var(--ease),
    border-color 0.2s;
}
:is(.hero, .today, .panel, .tile > .in, .tile.big .card, .hero-card .card:not(.web), .stat)[data-lit] {
  translate: 0 var(--lift);
  scale: var(--grow);
  box-shadow:
    0 28px 54px -22px rgba(0, 0, 0, 0.9),
    0 0 34px -6px color-mix(in srgb, var(--hue, var(--amber)) 50%, transparent),
    inset 0 1px 0 color-mix(in srgb, var(--hue, var(--amber)) 55%, transparent),
    inset 0 0 26px -12px color-mix(in srgb, var(--hue, var(--amber)) 80%, transparent);
  /* 跟鼠标时倾斜要跟得紧 */
  transition-duration: 0.45s, 0.2s, 0.35s, 0.35s, 0.35s, 0.2s;
}

/* 此刻 / 历史两个视图（见 views.js）：叠在同一格里，只显示地址对应的那个。
   隐藏用 content-visibility 而不是 display: none：不画、不能点，但保留算好的排版，
   切回来不用整页重新排版（历史视图约 16ms，正好压在过渡开始的那一帧） */
.views { display: grid; }
.view { grid-area: 1 / 1; min-width: 0; }
/* content-visibility 只是不画内容，盒子本身还在接鼠标：后面的历史视图叠在上面，会挡住此刻视图的悬停和点击 */
html:not([data-view="history"]) #view-history, html[data-view="history"] #view-now { content-visibility: hidden; pointer-events: none; }
/* 切换时只给内容做过渡：背景画布、顶部标签不截图，照常在跑 */
:root { view-transition-name: none; }
.views { view-transition-name: views; }
/* 只动 opacity 和 transform，全交给合成器：默认的外框动画会逐帧改宽高（两个视图不一样高），
   要在主线程排版，和背景画布抢时间就会掉帧；模糊滤镜对整页大小的截图也太重 */
::view-transition-group(views) { animation: none; }
::view-transition-image-pair(views) { isolation: auto; }
::view-transition-old(views), ::view-transition-new(views) { mix-blend-mode: normal; will-change: opacity, transform; }
::view-transition-old(views) { animation: 0.14s ease-in both view-out; }
::view-transition-new(views) { animation: 0.3s 0.04s cubic-bezier(0.2, 0.7, 0.2, 1) both view-in; }
html[data-dir="back"]::view-transition-old(views) { animation-name: view-out-back; }
html[data-dir="back"]::view-transition-new(views) { animation-name: view-in-back; }
@keyframes view-out { to { opacity: 0; transform: translate3d(-16px, 0, 0); } }
@keyframes view-in { from { opacity: 0; transform: translate3d(20px, 0, 0); } }
@keyframes view-out-back { to { opacity: 0; transform: translate3d(16px, 0, 0); } }
@keyframes view-in-back { from { opacity: 0; transform: translate3d(-20px, 0, 0); } }

/* 立绘：固定在背景里，此刻在右下、历史在左下，只显示当前视图那张。
   融进背景：压暗降饱和、边缘红蓝错位描边加一圈霓虹光、身后一团同色光晕，
   靠内容和底部的一侧渐隐；扫描线（body::after）照样盖在上面。平时慢慢上下浮，隔一阵闪一下细条错位的故障 */
.mascots { position: fixed; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.mascot {
  --h: min(90vh, 960px);
  position: absolute;
  bottom: -6vh;
  width: var(--h);
  height: var(--h);
  opacity: 0;
  transform: translate3d(var(--from, 40px), 12px, 0) scale(0.97);
  transition: opacity 0.7s ease, transform 0.9s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.mascot[data-for="now"] { --hue: var(--c-dev); --from: 48px; right: calc(var(--h) * -0.2); }
.mascot[data-for="history"] { --hue: var(--c-video); --from: -48px; left: calc(var(--h) * -0.2); }
html:not([data-view="history"]) .mascot[data-for="now"],
html[data-view="history"] .mascot[data-for="history"] { opacity: var(--show, 0.62); transform: none; }
/* 身后的光晕（radial 本身已经够软，不再加模糊） */
.mascot {
  background: radial-gradient(closest-side, color-mix(in srgb, var(--hue) 30%, transparent), transparent) center 60% / 80% 82% no-repeat;
  animation: mascot-float 7s ease-in-out infinite alternate;
}
.mascot[data-for="now"] { --art: url("/art/now.webp"); }
.mascot[data-for="history"] { --art: url("/art/history.webp"); --fade: to left; animation-delay: -3.5s; }
@keyframes mascot-float { to { translate: 0 -14px; } }
/* 靠内容的一侧和底部渐隐 */
.mascot img, .mascot::before, .mascot::after {
  --edge: linear-gradient(to top, transparent 2%, #000 34%), linear-gradient(var(--fade, to right), transparent 4%, #000 52%);
  mask-image: var(--edge);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
.mascot img {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  filter:
    saturate(0.85) brightness(0.76)
    drop-shadow(2px 0 0 rgba(255, 79, 216, 0.45))
    drop-shadow(-2px 0 0 rgba(47, 216, 255, 0.45))
    drop-shadow(0 0 18px color-mix(in srgb, var(--hue) 55%, transparent));
  animation: mascot-jitter 9s steps(1) infinite;
}
/* 故障：原图不动，上面叠两层同一张图，用两组疏密不同的横条遮罩切成很多细条（1–3px 一条、一簇一簇），
   一层带粉边往左错、一层带青边往右错；每一步挪一下遮罩，细条的位置跟着换 */
.mascot::before, .mascot::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--art) center / contain no-repeat;
  opacity: 0;
  mask-image: var(--edge), var(--fine), var(--coarse);
  animation: mascot-slice-a 9s steps(1) infinite;
}
.mascot::before {
  --fine: repeating-linear-gradient(#000 0 2px, transparent 2px 5px);
  --coarse: repeating-linear-gradient(#000 0 14px, transparent 14px 37px, #000 37px 45px, transparent 45px 71px);
  filter: saturate(1.3) brightness(0.95) drop-shadow(3px 0 0 rgba(255, 79, 216, 0.7));
}
.mascot::after {
  --fine: repeating-linear-gradient(#000 0 1px, transparent 1px 4px, #000 4px 7px, transparent 7px 9px);
  --coarse: repeating-linear-gradient(transparent 0 19px, #000 19px 31px, transparent 31px 52px, #000 52px 58px, transparent 58px 83px);
  filter: saturate(1.3) brightness(0.95) drop-shadow(-3px 0 0 rgba(47, 216, 255, 0.7));
  animation-name: mascot-slice-b;
}
.mascot[data-for="history"] img, .mascot[data-for="history"]::before, .mascot[data-for="history"]::after { animation-delay: -4s; }
/* 9 秒里只有最后零点几秒在闪 */
@keyframes mascot-jitter {
  0%, 94%, 96.6%, 100% { transform: none; }
  94.3% { transform: translateX(-1.5px); }
  95.1% { transform: translateX(1px); }
  95.9% { transform: translateX(-1px); }
}
@keyframes mascot-slice-a {
  0%, 94%, 96.6%, 100% { opacity: 0; transform: none; }
  94.2% { opacity: 1; transform: translateX(-5px); mask-position: 0 0, 0 0, 0 0, 0 0; }
  94.6% { transform: translateX(-9px); mask-position: 0 0, 0 0, 0 1px, 0 -120px; }
  95.0% { transform: translateX(-3px); mask-position: 0 0, 0 0, 0 3px, 0 -290px; }
  95.4% { transform: translateX(-7px); mask-position: 0 0, 0 0, 0 2px, 0 -455px; }
  95.8% { transform: translateX(-4px); mask-position: 0 0, 0 0, 0 4px, 0 -610px; }
  96.2% { transform: translateX(-2px); mask-position: 0 0, 0 0, 0 1px, 0 -770px; }
}
@keyframes mascot-slice-b {
  0%, 94%, 96.6%, 100% { opacity: 0; transform: none; }
  94.4% { opacity: 1; transform: translateX(6px); mask-position: 0 0, 0 0, 0 0, 0 0; }
  94.8% { transform: translateX(3px); mask-position: 0 0, 0 0, 0 2px, 0 170px; }
  95.2% { transform: translateX(8px); mask-position: 0 0, 0 0, 0 5px, 0 330px; }
  95.6% { transform: translateX(4px); mask-position: 0 0, 0 0, 0 1px, 0 520px; }
  96.0% { transform: translateX(6px); mask-position: 0 0, 0 0, 0 3px, 0 690px; }
}
/* 窄屏上立绘在卡片正后面：再淡一些，免得抢字 */
@media (max-width: 1100px) { .mascot { --show: 0.32; } }
@media (max-width: 640px) {
  .mascot { --show: 0.22; --h: min(78vh, 560px); bottom: -2vh; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
