/* ==========================================================================
   星野の小窝 · 全站样式（合并版）
   --------------------------------------------------------------------------
   本文件由以下 6 个源文件合并而来（顺序即优先级，勿随意调换）：
     1. tokens.css      设计令牌（唯一色彩来源，含暗色覆盖）
     2. base.css        重置 + 布局容器
     3. components.css  通用零件
     4. sections.css    板块样式
     5. animations.css  全部 @keyframes 与切换动画
     6. extra.css       toast 提示
   合并目的：减少请求数，消除慢主机上的 FOUC（样式割裂感）。
   ========================================================================== */

/* ==========================================================================
   樱花小窝 · 设计令牌（Design Tokens）
   --------------------------------------------------------------------------
   全站唯一色彩来源。改颜色只改这个文件，其它 CSS 一律引用变量。
   命名与原 React 版 src/config/tokens.js 一一对应。
   ========================================================================== */

:root {
  /* ── 品牌色（粉）色阶 ────────────────────────────── */
  --brand-50:  #fff5fa;
  --brand-100: #ffe6f3;
  --brand-200: #ffd3e8;
  --brand-300: #fbabd5;
  --brand-400: #f782c2;   /* 主强调色 */
  --brand-500: #ef62b0;
  --brand-600: #d94a99;

  /* ── 中性色阶 ────────────────────────────────────── */
  --n-0:   #ffffff;
  --n-50:  #f8f9fd;
  --n-100: #f5f6fb;
  --n-200: #eef0f8;
  --n-300: #e2e5f2;
  --n-400: #a3a9c3;
  --n-500: #6b7290;
  --n-600: #4f5675;
  --n-700: #333a5c;   /* 主文字 */
  --n-800: #262c4a;
  --n-900: #1a1f38;
  --n-950: #12152a;

  /* ── 语义槽位（暗色主题会覆盖这些）────────────────── */
  --page:        var(--n-100);
  --card:        var(--n-0);
  --card-border: var(--brand-100);
  --chip:        var(--n-50);
  --chip-border: var(--n-200);
  --line:        var(--n-200);
  --input:       var(--n-50);

  --text-primary:   var(--n-700);
  --text-secondary: var(--n-500);
  --text-muted:     var(--n-400);

  --accent:      var(--brand-400);
  --accent-soft: rgba(247, 130, 194, .10);
  --header-bg:   rgba(255, 255, 255, .85);
  --banner:      linear-gradient(120deg, var(--brand-100) 0%, #ffeef6 45%, #f3f0ff 100%);
  --shadow-card: 0 2px 12px -6px rgba(51, 58, 92, .12);

  /* ── 圆角 ────────────────────────────────────────── */
  --r-sm: .5rem;
  --r-md: .75rem;
  --r-card: 1.25rem;
  --r-full: 999px;

  /* ── 动效时长 ────────────────────────────────────── */
  --t-fast: .15s;
  --t-base: .25s;
  --t-slow: .4s;
}

/* ── 暗色主题：只覆盖语义槽位 ───────────────────────── */
:root[data-theme="dark"] {
  --page:        var(--n-900);
  --card:        #232946;
  --card-border: rgba(255, 255, 255, .07);
  --chip:        #2a3050;
  --chip-border: rgba(255, 255, 255, .06);
  --line:        #2c3350;
  --input:       #1a1f38;

  --text-primary:   #e6e8f7;
  --text-secondary: #aab0cc;
  --text-muted:     #7c83a5;

  --accent:      #f98ec4;
  --accent-soft: rgba(249, 142, 196, .14);
  --header-bg:   rgba(18, 21, 42, .85);
  --banner:      linear-gradient(120deg, #2a1f3d 0%, #241f38 45%, #1f2340 100%);
  --shadow-card: 0 6px 24px -12px rgba(0, 0, 0, .5);
}
/* ==========================================================================
   樱花小窝 · 基础样式
   --------------------------------------------------------------------------
   重置 + 排版 + 通用排版元素。依赖 tokens.css 先行加载。
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--page);
  color: var(--text-primary);
  font-family: Inter, system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
  font-size: 14px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transition: background var(--t-base), color var(--t-base);
}

h1, h2, h3, h4 { margin: 0; font-weight: 700; line-height: 1.4; }
p  { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img { max-width: 100%; display: block; -webkit-user-drag: none; user-select: none; }

a { color: inherit; text-decoration: none; }

button, input, textarea, select {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}

button { cursor: pointer; border: none; background: none; }

/* 键盘可达性：只在键盘导航时显示焦点框 */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* ── 布局容器 ────────────────────────────────────────── */
.wrap      { max-width: 1120px; margin: 0 auto; padding: 0 20px; }
.wrap-sm   { max-width: 760px;  margin: 0 auto; padding: 0 20px; }

/* ── 两栏栅格（桌面）─────────────────────────────────── */
.layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  margin-top: 20px;
}
@media (min-width: 1024px) {
  .layout { grid-template-columns: 2fr 1fr; }
}

/* ── 纵向堆叠间距 ────────────────────────────────────── */
.stack     { display: flex; flex-direction: column; gap: 16px; }
.stack-sm  { display: flex; flex-direction: column; gap: 10px; }
.stack-lg  { display: flex; flex-direction: column; gap: 28px; }

/* ── 可见性 ──────────────────────────────────────────── */
[hidden] { display: none !important; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── 工具类 ──────────────────────────────────────────── */
.no-scrollbar { scrollbar-width: none; -ms-overflow-style: none; }
.no-scrollbar::-webkit-scrollbar { display: none; }

.clamp-1, .clamp-2, .clamp-3 {
  display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden;
}
.clamp-1 { -webkit-line-clamp: 1; }
.clamp-2 { -webkit-line-clamp: 2; }
.clamp-3 { -webkit-line-clamp: 3; }

.muted    { color: var(--text-muted); }
.secondary{ color: var(--text-secondary); }

/* ── 降低动效偏好 ────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
/* ==========================================================================
   樱花小窝 · 组件样式
   --------------------------------------------------------------------------
   卡片 / 标签 / 按钮 / 头像 / 进度条 / 输入框 / 折叠面板 等通用零件。
   命名沿用 BEM 思路：块 .card，元素 .card__title，修饰 .card--hover。
   ========================================================================== */

/* ══ 卡片 ══════════════════════════════════════════════ */
.card {
  background: var(--card);
  border: 1px solid var(--card-border);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: 18px;
  transition: transform var(--t-base), box-shadow var(--t-base), border-color var(--t-base);
}
.card--hover:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 28px -14px rgba(51, 58, 92, .28);
  border-color: var(--accent);
}
.card--flat { box-shadow: none; }
.card--link { display: block; }

/* ══ 区块标题 ══════════════════════════════════════════ */
.sec-title {
  display: flex; align-items: center; gap: 8px;
  font-size: 15px; font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 14px;
}
.sec-title__icon { font-size: 15px; }
.sec-title__extra {
  margin-left: auto;
  font-size: 11.5px; font-weight: 500;
  color: var(--text-muted);
}
.sec-title--divider {
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

/* ══ 标签 ══════════════════════════════════════════════ */
.tag {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 10px;
  border-radius: var(--r-full);
  font-size: 11.5px; font-weight: 500;
  transition: all var(--t-fast);
  white-space: nowrap;
}
.tag--sm { padding: 2px 8px; font-size: 10.5px; }
.tag--soft    { background: var(--accent-soft); color: var(--accent); }
.tag--solid   { background: var(--accent); color: #fff; }
.tag--outline { background: transparent; color: var(--text-secondary); border: 1px solid var(--line); }
.tag--click { cursor: pointer; }
.tag--click:hover { background: var(--accent); color: #fff; border-color: var(--accent); }

/* ══ 按钮 ══════════════════════════════════════════════ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 16px;
  border-radius: var(--r-full);
  font-size: 12.5px; font-weight: 600;
  transition: all var(--t-fast);
}
.btn--primary {
  background: var(--accent); color: #fff;
}
.btn--primary:hover { filter: brightness(1.06); transform: translateY(-1px); }
.btn--ghost {
  background: var(--chip); color: var(--text-secondary);
}
.btn--ghost:hover { color: var(--accent); }
.btn--block { width: 100%; }

/* ══ 头像 ══════════════════════════════════════════════ */
.avatar {
  position: relative;
  border-radius: 50%;
  overflow: hidden;
  background: var(--chip);
  flex-shrink: 0;
}
.avatar--sm { width: 32px;  height: 32px; }
.avatar--md { width: 44px;  height: 44px; }
.avatar--lg { width: 64px;  height: 64px; }
.avatar--xl { width: 84px;  height: 84px; }
.avatar--rounded { border-radius: var(--r-md); }
.avatar--ring { box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--accent); }
.avatar img { width: 100%; height: 100%; object-fit: cover; }

.avatar__status {
  position: absolute; right: 2px; bottom: 2px;
  width: 11px; height: 11px; border-radius: 50%;
  background: #3fcf8e;
  border: 2px solid var(--card);
  animation: soft-pulse 2s ease-in-out infinite;
}

/* ══ 进度条 ════════════════════════════════════════════ */
.bar {
  height: 7px;
  background: var(--chip);
  border-radius: var(--r-full);
  overflow: hidden;
}
.bar--thin { height: 4px; }
.bar__fill {
  height: 100%;
  border-radius: var(--r-full);
  background: linear-gradient(90deg, var(--brand-300), var(--accent));
  transition: width var(--t-slow) ease;
}
.bar__fill--plain { background: var(--accent); }

/* ══ 输入框 ════════════════════════════════════════════ */
.input {
  width: 100%;
  padding: 9px 14px;
  background: var(--input);
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  font-size: 12.5px;
  outline: none;
  transition: border-color var(--t-fast);
}
.input::placeholder { color: var(--text-muted); }
.input:focus { border-color: var(--accent); }

/* ══ 筛选标签组 ════════════════════════════════════════ */
.filters { display: flex; flex-wrap: wrap; gap: 7px; }
.filter {
  padding: 5px 13px;
  border-radius: var(--r-full);
  font-size: 12px; font-weight: 500;
  background: var(--chip); color: var(--text-secondary);
  transition: all var(--t-fast);
}
.filter:hover { color: var(--accent); }
.filter.is-active { background: var(--accent); color: #fff; }

.filters--text .filter {
  background: none; padding: 4px 2px; border-radius: 0;
}
.filters--text .filter.is-active {
  background: none; color: var(--accent);
  box-shadow: inset 0 -2px 0 var(--accent);
}

/* ══ 折叠面板 ══════════════════════════════════════════ */
.acc { border-radius: var(--r-md); overflow: hidden; }
.acc__item {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  margin-bottom: 8px;
  background: var(--card);
  overflow: hidden;
}
.acc__q {
  width: 100%; display: flex; align-items: center; gap: 8px;
  padding: 13px 16px; text-align: left;
  font-size: 13px; font-weight: 600;
  color: var(--text-primary);
}
.acc__mark {
  margin-left: auto; color: var(--accent);
  transition: transform var(--t-base);
  font-size: 12px;
}
.acc__item.is-open .acc__mark { transform: rotate(45deg); }
.acc__a {
  max-height: 0; overflow: hidden;
  transition: max-height var(--t-base) ease;
}
.acc__inner {
  padding: 0 16px 14px;
  font-size: 12.5px; color: var(--text-secondary);
  line-height: 1.75;
}
.acc__item.is-open .acc__a { max-height: 260px; }

/* ══ 页面头（关于页等）══════════════════════════════════ */
.page-head { padding: 28px 0 8px; }
.page-head h1 { font-size: 24px; }
.page-head p  { margin-top: 6px; color: var(--text-secondary); font-size: 13px; }
/* ==========================================================================
   樱花小窝 · 板块样式
   --------------------------------------------------------------------------
   导航 / 页脚 / 悬浮工具 / 欢迎横幅 / 资料卡 / 各侧栏小挂件 /
   文章卡片 / 正文排版 / 时间线 / 技能 / 项目 / 友链 / 留言板 / 联系卡。
   ========================================================================== */

/* ══ 顶部导航 ══════════════════════════════════════════ */
.navbar {
  position: sticky; top: 0; z-index: 40;
  background: var(--header-bg);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.navbar__inner {
  max-width: 1120px; margin: 0 auto; padding: 0 20px;
  height: 62px; display: flex; align-items: center; gap: 22px;
}
.brand {
  display: flex; align-items: center; gap: 6px;
  font-size: 15px; font-weight: 700; flex-shrink: 0;
}
.brand__flower { color: var(--accent); }

.nav { display: flex; gap: 20px; font-size: 13.5px; }
.nav a { color: var(--text-secondary); transition: color var(--t-fast); }
.nav a:hover, .nav a.is-active { color: var(--accent); }

.navbar__right { margin-left: auto; display: flex; align-items: center; gap: 8px; }

.search {
  display: flex; align-items: center; gap: 6px;
  background: var(--chip); border-radius: var(--r-full);
  padding: 5px 12px;
}
.search input {
  background: none; border: none; outline: none;
  font-size: 12px; width: 92px;
}
.search input::placeholder { color: var(--text-muted); }

.icon-btn {
  width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; background: var(--chip);
  transition: transform var(--t-fast);
}
.icon-btn:hover { transform: scale(1.08); }

@media (max-width: 640px) {
  .search { display: none; }
  .nav { gap: 14px; font-size: 13px; }
}

/* ══ 页脚 ══════════════════════════════════════════════ */
.footer {
  margin-top: 40px; padding: 28px 0;
  border-top: 1px solid var(--line);
}
.footer__inner {
  max-width: 1120px; margin: 0 auto; padding: 0 20px;
  display: flex; flex-wrap: wrap; gap: 12px;
  align-items: center; justify-content: space-between;
  font-size: 11.5px; color: var(--text-muted);
}
.footer__right { display: flex; align-items: center; gap: 12px; }
.footer__flower { color: var(--accent); }

/* ══ 悬浮工具（右下角）═════════════════════════════════ */
.floaters {
  position: fixed; right: 18px; bottom: 22px; z-index: 45;
  display: flex; flex-direction: column; gap: 9px;
}
.floater {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--card);
  border: 1px solid var(--card-border);
  box-shadow: var(--shadow-card);
  display: flex; align-items: center; justify-content: center;
  font-size: 15px;
  transition: transform var(--t-fast);
}
.floater:hover { transform: scale(1.1); }
.floater.is-playing { animation: spin-slow 3.5s linear infinite; }

/* ══ 樱花飘落层 ════════════════════════════════════════ */
.petals {
  position: fixed; inset: 0; z-index: 1;
  pointer-events: none; overflow: hidden;
}
.petal {
  position: absolute; top: -8%;
  font-size: 13px; opacity: .55;
  animation: petal-fall linear infinite;
}

/* ══ 欢迎横幅 ══════════════════════════════════════════ */
.banner {
  position: relative; overflow: hidden;
  border-radius: var(--r-card);
  padding: 30px 28px;
  background: var(--banner);
  border: 1px solid var(--card-border);
}
.banner__hi   { font-size: 22px; font-weight: 800; }
.banner__sub  { margin-top: 8px; font-size: 13px; color: var(--text-secondary); }
.banner__meta {
  margin-top: 14px; display: flex; flex-wrap: wrap; gap: 8px;
}
.banner__deco {
  position: absolute; right: 22px; bottom: -6px;
  font-size: 76px; opacity: .16; line-height: 1;
}

/* ══ 资料卡 ════════════════════════════════════════════ */
.profile { display: flex; gap: 16px; align-items: flex-start; }
.profile__name { font-size: 17px; font-weight: 700; }
.profile__cn   { font-size: 12px; color: var(--accent); margin-top: 2px; }
.profile__role { font-size: 12px; color: var(--text-secondary); margin-top: 4px; }
.profile__bio  { margin-top: 10px; font-size: 12.5px; color: var(--text-secondary); line-height: 1.75; }

.identity { margin-top: 12px; display: flex; flex-wrap: wrap; gap: 7px; }
.identity__item {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: var(--r-full);
  background: var(--chip); font-size: 11px;
  color: var(--text-secondary);
}
.identity__label { color: var(--text-muted); }

.socials { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 8px; }
.social {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 12px; border-radius: var(--r-full);
  background: var(--chip); font-size: 11.5px;
  color: var(--text-secondary);
  transition: all var(--t-fast);
}
.social:hover { background: var(--accent); color: #fff; }

/* ══ 文章卡片（列表项）═════════════════════════════════ */
.postcard {
  display: flex; gap: 14px; align-items: stretch;
  padding: 14px;
}
.postcard__cover {
  width: 124px; height: 84px; flex-shrink: 0;
  border-radius: var(--r-md); overflow: hidden;
  background: var(--chip);
}
.postcard__cover img { width: 100%; height: 100%; object-fit: cover; }
.postcard__body { min-width: 0; display: flex; flex-direction: column; }
.postcard__title {
  font-size: 14.5px; font-weight: 700;
  transition: color var(--t-fast);
}
.postcard:hover .postcard__title { color: var(--accent); }
.postcard__excerpt {
  margin-top: 6px; font-size: 12px;
  color: var(--text-secondary); line-height: 1.7;
}
.postcard__meta {
  margin-top: auto; padding-top: 8px;
  display: flex; flex-wrap: wrap; gap: 10px;
  font-size: 11px; color: var(--text-muted);
}
.postcard__tags { display: flex; gap: 5px; }

@media (max-width: 560px) {
  .postcard__cover { width: 92px; height: 68px; }
}

/* ══ 侧栏小挂件 ════════════════════════════════════════ */
.widget-list { display: flex; flex-direction: column; gap: 12px; }
.widget-row {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 12px;
}
.widget-row__name { color: var(--text-primary); font-weight: 500; }
.widget-row__val  { margin-left: auto; color: var(--text-muted); font-size: 11.5px; }
.widget-sub { font-size: 11px; color: var(--text-muted); margin-top: 6px; }

.clock__time {
  font-size: 26px; font-weight: 800;
  letter-spacing: .5px; font-variant-numeric: tabular-nums;
}
.clock__greet { margin-top: 4px; font-size: 12px; color: var(--text-secondary); }
.clock__date  { margin-top: 2px; font-size: 11px; color: var(--text-muted); }

/* 标签云 */
.tagcloud { display: flex; flex-wrap: wrap; gap: 7px; }

/* 项目横滚 */
.projscroll {
  display: flex; gap: 10px; overflow-x: auto;
  padding-bottom: 6px; scroll-snap-type: x mandatory;
}
.projscroll__item {
  flex: 0 0 156px; scroll-snap-align: start;
  padding: 13px; border-radius: var(--r-md);
  background: var(--chip);
  transition: transform var(--t-fast);
}
.projscroll__item:hover { transform: translateY(-2px); }
.projscroll__icon {
  width: 30px; height: 30px; border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; margin-bottom: 8px;
}
.projscroll__name { font-size: 12.5px; font-weight: 600; }
.projscroll__desc {
  margin-top: 4px; font-size: 11px;
  color: var(--text-secondary); line-height: 1.6;
}
.projscroll__star { margin-top: 8px; font-size: 11px; color: var(--text-muted); }

/* 友链 */
.friends { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.friend {
  padding: 9px 12px; border-radius: var(--r-md);
  background: var(--chip); font-size: 12px;
  color: var(--text-secondary); text-align: center;
  transition: all var(--t-fast);
}
.friend:hover { background: var(--accent); color: #fff; }

/* 留言板 */
.comments { display: flex; flex-direction: column; gap: 12px; }
.comment { display: flex; gap: 10px; }
.comment__body { min-width: 0; flex: 1; }
.comment__head {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 12px;
}
.comment__name { font-weight: 600; }
.comment__time { margin-left: auto; font-size: 10.5px; color: var(--text-muted); }
.comment__text { margin-top: 2px; font-size: 12px; color: var(--text-secondary); line-height: 1.7; }
.comment-form { display: flex; gap: 8px; margin-top: 14px; }
.comment-form .input { flex: 1; }

/* ══ 文章正文排版 ══════════════════════════════════════ */
.article { max-width: 760px; margin: 0 auto; padding: 0 20px; }
.article__title {
  font-size: 26px; line-height: 1.45; margin-bottom: 12px;
}
.article__meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
  font-size: 12px; color: var(--text-muted);
}
.article__cover {
  border-radius: var(--r-card); overflow: hidden; margin: 22px 0;
}
.article__cover img { width: 100%; height: 260px; object-fit: cover; }
.article__tags { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 20px; }

.content { font-size: 14px; line-height: 1.9; color: var(--text-secondary); }
.content > * + * { margin-top: 16px; }
.content p { color: var(--text-secondary); }

.content h2 {
  position: relative; padding-left: 14px;
  font-size: 16.5px; color: var(--text-primary);
  margin-top: 28px;
}
.content h2::before {
  content: ''; position: absolute; left: 0; top: 50%;
  transform: translateY(-50%);
  width: 4px; height: 16px; border-radius: 2px;
  background: var(--accent);
}

.content blockquote {
  padding: 12px 16px;
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  font-style: italic;
  color: var(--text-primary);
}

.content pre {
  padding: 14px 16px;
  background: var(--input);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow-x: auto;
  font-family: "JetBrains Mono", ui-monospace, Consolas, monospace;
  font-size: 12.5px; line-height: 1.7;
  color: var(--text-primary);
}

/* 阅读进度条 */
.readbar {
  position: sticky; top: 62px; z-index: 30; height: 3px;
}
.readbar__fill { height: 100%; width: 0; background: var(--accent); }

/* 作者卡 */
.authorbox { display: flex; gap: 14px; align-items: flex-start; flex-wrap: wrap; }
.authorbox__body { flex: 1; min-width: 200px; }
.authorbox__name { font-size: 14px; font-weight: 700; }
.authorbox__bio  { margin-top: 6px; font-size: 12px; color: var(--text-secondary); line-height: 1.75; }
.authorbox__tags { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 6px; }

/* 相关阅读 */
.related { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 700px) { .related { grid-template-columns: repeat(3, 1fr); } }
.related__card { padding: 14px; }
.related__title { font-size: 13px; font-weight: 600; line-height: 1.55; }
.related__meta  { margin-top: 8px; font-size: 10.5px; color: var(--text-muted); }

/* ══ 时间线 ════════════════════════════════════════════ */
.timeline { position: relative; padding-left: 22px; }
.timeline::before {
  content: ''; position: absolute; left: 5px; top: 4px; bottom: 4px;
  border-left: 2px dashed var(--line);
}
.timeline__item { position: relative; padding-bottom: 20px; }
.timeline__item:last-child { padding-bottom: 0; }
.timeline__dot {
  position: absolute; left: -22px; top: 5px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--card); border: 3px solid var(--accent);
}
.timeline__period { font-size: 11px; color: var(--accent); font-weight: 600; }
.timeline__title  { margin-top: 3px; font-size: 13.5px; font-weight: 700; }
.timeline__org    { font-size: 11.5px; color: var(--text-muted); }
.timeline__desc   { margin-top: 5px; font-size: 12px; color: var(--text-secondary); line-height: 1.7; }

/* ══ 技能列表 ══════════════════════════════════════════ */
.skill { margin-bottom: 14px; }
.skill:last-child { margin-bottom: 0; }
.skill__head {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; margin-bottom: 6px;
}
.skill__level { margin-left: auto; font-size: 11.5px; color: var(--text-muted); }

/* ══ 项目网格（关于页）═════════════════════════════════ */
.projgrid { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 700px) { .projgrid { grid-template-columns: 1fr 1fr; } }
.projcard { padding: 16px; }
.projcard__head { display: flex; align-items: center; gap: 10px; }
.projcard__icon {
  width: 34px; height: 34px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center; font-size: 17px;
}
.projcard__name { font-size: 13.5px; font-weight: 700; }
.projcard__tag  { margin-left: auto; }
.projcard__desc { margin-top: 10px; font-size: 12px; color: var(--text-secondary); line-height: 1.7; }
.projcard__star { margin-top: 8px; font-size: 11px; color: var(--text-muted); }

/* ══ 联系卡 ════════════════════════════════════════════ */
.contact {
  position: relative; overflow: hidden;
  border-radius: var(--r-card); padding: 26px 24px;
  background: var(--banner);
  border: 1px solid var(--card-border);
  text-align: center;
}
.contact__title { font-size: 17px; font-weight: 800; }
.contact__sub   { margin-top: 8px; font-size: 12.5px; color: var(--text-secondary); }
.contact__btns  { margin-top: 16px; display: flex; flex-wrap: wrap; gap: 9px; justify-content: center; }

/* ══ 返回链接 ══════════════════════════════════════════ */
.backlink {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12.5px; color: var(--text-secondary);
  margin-bottom: 18px;
  transition: color var(--t-fast);
}
.backlink:hover { color: var(--accent); }
/* ==========================================================================
   樱花小窝 · 动画
   --------------------------------------------------------------------------
   全部 @keyframes 集中在这里。降低动效偏好在 base.css 统一处理。
   ========================================================================== */

/* 樱花飘落：从顶部飘到底部，边落边左右摇摆 */
@keyframes petal-fall {
  0%   { transform: translateY(-10vh) translateX(0)     rotate(0deg);   opacity: 0; }
  10%  { opacity: .6; }
  50%  { transform: translateY(45vh)  translateX(28px)  rotate(140deg); }
  90%  { opacity: .5; }
  100% { transform: translateY(105vh) translateX(-18px) rotate(300deg); opacity: 0; }
}

/* 淡入上移 */
@keyframes fade-up {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* 柔光脉冲（在线小圆点） */
@keyframes soft-pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: .55; transform: scale(.88); }
}

/* 慢速旋转（音乐播放中） */
@keyframes spin-slow {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* 心跳 */
@keyframes heartbeat {
  0%, 100% { transform: scale(1); }
  25%      { transform: scale(1.14); }
  40%      { transform: scale(1); }
  60%      { transform: scale(1.08); }
}

/* ── 工具类 ──────────────────────────────────────────── */
.anim-fade-up   { animation: fade-up .45s ease both; }
.anim-heartbeat { animation: heartbeat 1.6s ease-in-out infinite; }

/* ==========================================================================
   切换与入场动画（v2 追加）
   ========================================================================== */

/* ── 通用：上浮 / 下落 ───────────────────────────────── */
@keyframes rise-in {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes drop-in {
  from { opacity: 0; transform: translateY(-14px); }
  to   { opacity: 1; transform: translateY(0); }
}
.anim-rise { animation: rise-in .6s cubic-bezier(.22,.9,.34,1) both; }

/* ── 首次加载：导航下落 + 内容错峰入场 ───────────────── */
.navbar { animation: drop-in .5s ease-out both; }
.footer { animation: rise-in .6s .25s ease-out both; }

/* ── 主题切换：圆形扩散（View Transitions）──────────── */
::view-transition-old(root),
::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
html.theme-anim::view-transition-new(root) {
  animation: theme-reveal .55s ease-in-out both;
}
@keyframes theme-reveal {
  from { clip-path: circle(0 at var(--theme-pos, 95% 24px)); }
  to   { clip-path: circle(150% at var(--theme-pos, 95% 24px)); }
}
/* 降级：不支持 View Transitions 时给全局一个颜色过渡 */
html.theme-fade body,
html.theme-fade body * {
  transition: background-color .35s ease, color .3s ease, border-color .35s ease !important;
}

/* ── 进入文章：页面级跨文档过渡（Chromium 126+）──────── */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
/* 主题切换时不能用这两条（会破坏圆形扩散），所以限定在非 theme-anim 时 */
html:not(.theme-anim)::view-transition-old(root) { animation: vt-out .3s ease both; }
html:not(.theme-anim)::view-transition-new(root) { animation: vt-in .38s ease both; }
@keyframes vt-out { to { opacity: 0; transform: translateY(-10px); } }
@keyframes vt-in  { from { opacity: 0; transform: translateY(12px); } }

/* ── 滚动进入视口前隐藏（由 js/anim.js 控制揭示）─────── */
.pre-reveal { opacity: 0; transform: translateY(16px); }
.pre-reveal.anim-in { animation: rise-in .55s cubic-bezier(.22,.9,.34,1) both; }

/* ==========================================================================
   樱花小窝 · 附加样式（toast 提示等）
   ========================================================================== */

.toast {
  position: fixed;
  left: 50%; bottom: 34px;
  transform: translate(-50%, 16px);
  z-index: 90;
  padding: 9px 18px;
  border-radius: var(--r-full);
  background: var(--text-primary);
  color: var(--card);
  font-size: 12.5px;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-base), transform var(--t-base);
  box-shadow: 0 8px 24px -10px rgba(0, 0, 0, .4);
}
.toast.is-show {
  opacity: 1;
  transform: translate(-50%, 0);
}
