/* ============================================
   Xinyu · Portfolio — global styles
   风格来源：reckon.house 设计基因（暖纸 + 标本卡 + 铅笔标注）
   ============================================ */

/* ---------- reset ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
}

html {
  scroll-behavior: smooth;
}

body {
  background: var(--color-bg);
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  min-height: 100dvh;
}

img {
  max-width: 100%;
  display: block;
}

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

button {
  font: inherit;
  border: none;
  background: none;
  color: inherit;
}

::selection {
  background: var(--color-accent);
  color: var(--color-ink);
}

:focus-visible {
  outline: 2px solid var(--color-ink);
  outline-offset: 3px;
  border-radius: 4px;
}

/* 桌面端隐藏原生指针（由小猫指针接管）；触屏设备保持原生 */
@media (pointer: fine) {
  html.has-cat-cursor,
  html.has-cat-cursor a,
  html.has-cat-cursor button,
  html.has-cat-cursor [role="button"] {
    cursor: none;
  }
}

/* 漂浮公式/代码标注层（CSS 合成器动画驱动） */
#annotations-layer {
  position: fixed;
  inset: 0;
  z-index: var(--z-bg);
  pointer-events: none;
  overflow: hidden;
}

.bg-glyph {
  position: absolute;
  top: var(--gy);
  left: var(--gx);
  font-family: var(--font-mono);
  font-size: var(--gsize);
  color: #8c8578;
  opacity: var(--galpha);
  white-space: nowrap;
  rotate: var(--grot);
  animation:
    glyph-drift var(--gdur) linear var(--gdelay) infinite,
    glyph-breathe var(--gbreathe) ease-in-out var(--gdelay) infinite alternate;
}

@keyframes glyph-drift {
  from { transform: translateY(12vh); }
  to   { transform: translateY(-24vh); }
}

@keyframes glyph-breathe {
  from { opacity: calc(var(--galpha) * 0.55); }
  to   { opacity: var(--galpha); }
}

/* 手绘涂鸦（正弦波/角度/方框/猫爪…），静置 + 呼吸 */
.bg-sketch {
  position: absolute;
  top: var(--gy);
  left: var(--gx);
  width: calc(96px * var(--gscale, 1));
  color: #8c8578;
  opacity: var(--galpha);
  rotate: var(--grot);
  animation: glyph-breathe var(--gbreathe) ease-in-out var(--gdelay) infinite alternate;
}

.bg-sketch svg {
  width: 100%;
  height: auto;
  display: block;
}

/* ---------- 布局 ---------- */
.container {
  max-width: 1440px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

main section {
  padding-block: calc(var(--space-section) / 2);
}

#projects {
  padding-bottom: var(--space-8);
}

#education {
  padding-top: var(--space-8);
}

/* ---------- 顶部条 ---------- */
.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-6) var(--gutter);
  position: relative;
  z-index: 10;
}

.breadcrumb {
  font-size: var(--text-meta);
  font-weight: 500;
  display: flex;
  gap: 0.5em;
  align-items: center;
}

.breadcrumb .crumb-root {
  font-weight: 700;
}

.breadcrumb .sep {
  color: var(--color-muted);
}

.breadcrumb .crumb-current {
  color: var(--color-muted);
}

/* 语言切换按钮 */
.lang-toggle {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  padding: 3px;
  font-size: var(--text-meta);
  font-weight: 500;
}

.lang-toggle button {
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  color: var(--color-muted);
  transition: color var(--duration-fast), background var(--duration-fast);
}

.lang-toggle button[aria-pressed="true"] {
  background: var(--color-ink);
  color: var(--color-nav-fg);
}

.lang-toggle button:not([aria-pressed="true"]):hover {
  color: var(--color-ink);
}

/* ---------- 章节胶囊标 ---------- */
.section-pill {
  display: inline-block;
  font-size: var(--text-meta);
  font-weight: 500;
  letter-spacing: 0.02em;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-pill);
  padding: 0.45em 1.1em;
  margin-bottom: var(--space-8);
}

/* ---------- Hero / Overview ---------- */
.hero {
  padding-top: var(--space-8);
}

.hero-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-8);
}

@media (min-width: 900px) {
  .hero-layout {
    grid-template-columns: minmax(0, 1fr) 220px;
    gap: var(--space-12);
    align-items: start;
  }
}

.hero-intro {
  font-size: var(--text-intro);
  line-height: 1.45;
  font-weight: 400;
  max-width: 26em;
  letter-spacing: -0.01em;
}

.hero-intro strong {
  font-weight: 700;
}

/* 个人照片 — 小小的、液态框 + 铅笔标注 */
.hero-photo {
  position: relative;
  width: min(200px, 48vw);
  justify-self: start;
}

@media (min-width: 900px) {
  .hero-photo {
    justify-self: end;
    margin-top: 0.5rem;
  }
}

.hero-photo .photo-frame {
  border-radius: var(--blob-a);
  overflow: hidden;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  aspect-ratio: 4 / 5;
  transition: border-radius var(--duration-slow) var(--ease-liquid);
}

.hero-photo:hover .photo-frame {
  border-radius: var(--blob-b);
}

.hero-photo .photo-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.photo-caption {
  position: absolute;
  bottom: -1.6em;
  left: 8%;
  font-size: var(--text-annotation);
  color: var(--color-faint);
  transform: rotate(-2deg);
}

/* 标本卡元信息 Field / Strengths */
.specimen {
  margin-top: var(--space-12);
  display: grid;
  gap: 0.55em;
  font-size: var(--text-meta);
  max-width: 60ch;
}

.specimen-row {
  display: flex;
  gap: 0.6em;
  flex-wrap: wrap;
}

.specimen-row dt {
  font-weight: 700;
}

.specimen-row dd {
  color: var(--color-ink);
}

.specimen-row dd .sub {
  color: var(--color-muted);
}

/* ---------- 我的作品：分类分组 ---------- */
.work-groups {
  display: grid;
  gap: clamp(2rem, 3vw, 2.75rem);
  margin-top: var(--space-6);
  width: min(1400px, calc(100vw - 100px));
  max-width: none;
  margin-inline: auto;
  position: relative;
  left: 50%;
  transform: translateX(-50%);
}

.work-group-head {
  display: flex;
  align-items: baseline;
  margin-bottom: var(--space-6);
}

.work-group-head h3 {
  font-family: var(--font-mono);
  font-size: var(--text-annotation);
  color: var(--color-muted);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* ---------- 跨栏猫咪巡逻 ---------- */
.cat-patrol {
  position: relative;
  width: 100%;
  height: clamp(78px, 6vw, 96px);
  overflow: hidden;
  isolation: isolate;
}

.cat-patrol-cat {
  position: absolute;
  left: 0;
  bottom: 2px;
  z-index: 0;
  width: clamp(80px, 7vw, 104px);
  translate: -100% 0;
  animation: catPatrol 28s ease-in-out infinite;
}

.cat-patrol-cat::after {
  content: "";
  position: absolute;
  z-index: 0;
  left: 22%;
  right: 22%;
  bottom: 5px;
  height: 6px;
  border-radius: 50%;
  background: rgba(26, 26, 26, 0.12);
  filter: blur(4px);
}

.cat-patrol-cat img {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: auto;
  pointer-events: none;
  user-select: none;
  animation: catPatrolFacing 28s linear infinite;
}

@keyframes catPatrol {
  0% {
    left: 0;
    translate: -100% 0;
  }
  8% {
    left: 10%;
    translate: -80% -2px;
  }
  20% {
    left: 32%;
    translate: -60% 1px;
  }
  34% {
    left: 61%;
    translate: -35% -2px;
  }
  47%,
  53% {
    left: 100%;
    translate: 0 0;
  }
  65% {
    left: 72%;
    translate: -28% -2px;
  }
  80% {
    left: 39%;
    translate: -62% 1px;
  }
  92% {
    left: 12%;
    translate: -85% -2px;
  }
  100% {
    left: 0;
    translate: -100% 0;
  }
}

@keyframes catPatrolFacing {
  0%,
  49% {
    transform: scaleX(-1);
  }
  51%,
  100% {
    transform: scaleX(1);
  }
}

/* ---------- 作品网格 ----------
   参考站桌面实测：
   - 主体 160 × 160px；图片在主体内放大至 120%
   - 单卡（含两行说明）约 160 × 200px
   - 一行 4 张，行宽最高 1400px，两端对齐；行间 100px

   “破壳”使用两张同源图片：上层在圆角框内，底层放进更大的 SVG mask，
   并保持相同裁切坐标。这样越界部分是真实产品画面，而不是装饰色块。
--------------------------------------------------------------------------------------- */
.projects-grid {
  display: grid;
  grid-template-columns: repeat(4, 160px);
  justify-content: space-between;
  align-items: start;
  column-gap: 0;
  row-gap: 56px;
  overflow: visible;
}

.project-card {
  display: block;
  width: 160px;
  overflow: visible;
  --card-size: 160px;
}

.card-float {
  width: var(--card-size);
  transform-style: preserve-3d;
  animation: card-float var(--dur, 9s) ease-in-out var(--delay, 0s) infinite;
  will-change: transform;
}

@keyframes card-float {
  0%, 100% {
    transform: perspective(700px) translate3d(0, 0, 0)
      rotateY(var(--tilt, 0deg));
  }
  25% {
    transform: perspective(700px)
      translate3d(var(--ampX, 0px), calc(var(--amp, -3px) * 0.55), 0)
      rotateY(0deg);
  }
  50% {
    transform: perspective(700px) translate3d(0, var(--amp, -3px), 0)
      rotateY(calc(var(--tilt, 0deg) * -1));
  }
  75% {
    transform: perspective(700px)
      translate3d(calc(var(--ampX, 0px) * -1), calc(var(--amp, -3px) * 0.55), 0)
      rotateY(0deg);
  }
}

.project-card .card-visual {
  position: relative;
  width: var(--card-size);
  height: var(--card-size);
  aspect-ratio: 1;
  overflow: visible;
  transform: scale(var(--rs, 1));
  transform-origin: center;
  transition: transform var(--duration-normal) var(--ease-out-expo);
}

.card-clip {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: 22.2222%;
  background: var(--color-surface-alt);
}

.card-image,
.card-breakout-image {
  position: absolute;
  width: var(--card-size);
  height: var(--card-size);
  max-width: none;
  object-fit: cover;
  transform: scale(1.2);
  transform-origin: center;
  transition: filter 450ms ease, transform 450ms var(--ease-out-expo);
}

.card-image {
  inset: 0;
}

.card-breakout {
  position: absolute;
  z-index: 0;
  left: var(--blot-left);
  top: var(--blot-top);
  width: var(--blot-width);
  height: var(--blot-height);
  overflow: hidden;
  opacity: 0;
  transform: scale(0.12);
  transform-origin: var(--blot-origin, center);
  -webkit-mask-image: var(--ink);
  mask-image: var(--ink);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  pointer-events: none;
  will-change: transform, opacity;
}

.card-breakout-image {
  left: var(--image-left);
  top: var(--image-top);
}

/* Ben’s Journeys：首页三张封面按参考录屏的节奏循环。
   主体与破形层共用同一组时序，所以越界画面不会和卡片内部错位。 */
.card-cover-carousel {
  opacity: 0;
  clip-path: inset(0 100% 0 0);
  animation: card-cover-carousel 9.6s linear var(--slide-delay, 0s) infinite;
  will-change: opacity, clip-path;
}

@keyframes card-cover-carousel {
  0% {
    opacity: 0;
    clip-path: inset(0 100% 0 0);
  }
  4% {
    opacity: 1;
    clip-path: inset(0 0 0 0);
  }
  30% {
    opacity: 1;
    clip-path: inset(0 0 0 0);
  }
  36% {
    opacity: 0;
    clip-path: inset(0 0 0 100%);
  }
  100% {
    opacity: 0;
    clip-path: inset(0 0 0 100%);
  }
}

.project-card.is-visible .card-breakout {
  animation: breakout-in 900ms cubic-bezier(0.16, 0.9, 0.2, 1.03)
    var(--blot-delay, 0s) both;
}

@keyframes breakout-in {
  0% { opacity: 0; transform: scale(0.12); }
  35% { opacity: 1; }
  100% { opacity: 1; transform: scale(1); }
}

/* 参考站原始 SVG 遮罩与 225px 坐标系，全部按卡片尺寸同比缩放。 */
.card-mask-ref-tl2 {
  --ink: url("../assets/masks/reckon/top-left2-ink.svg");
  --blot-width: 145.3333%;
  --blot-height: 141.3333%;
  --blot-left: -45.3333%;
  --blot-top: -41.3333%;
  --image-left: 31.1927%;
  --image-top: 29.2453%;
  --blot-origin: 31.1927% 29.2453%;
}

.card-mask-ref-tr {
  --ink: url("../assets/masks/reckon/top-right-ink.svg");
  --blot-width: 140.4444%;
  --blot-height: 144.4444%;
  --blot-left: 0%;
  --blot-top: -44.4444%;
  --image-left: 0%;
  --image-top: 30.7692%;
  --blot-origin: 71.2025% 30.7692%;
}

.card-mask-ref-sl1 {
  --ink: url("../assets/masks/reckon/side-left1-ink.svg");
  --blot-width: 146.2222%;
  --blot-height: 125.7778%;
  --blot-left: -46.2222%;
  --blot-top: -3.5556%;
  --image-left: 31.6109%;
  --image-top: 2.8262%;
  --blot-origin: 31.6109% 42.5795%;
}

.card-mask-ref-sr1 {
  --ink: url("../assets/masks/reckon/side-right1-ink.svg");
  --blot-width: 132.8889%;
  --blot-height: 100%;
  --blot-left: 0%;
  --blot-top: 0%;
  --image-left: 0%;
  --image-top: 0%;
  --blot-origin: 75.2508% 50%;
}

.card-mask-ref-bl {
  --ink: url("../assets/masks/reckon/bottom-left-ink.svg");
  --blot-width: 142.2222%;
  --blot-height: 148.4444%;
  --blot-left: -42.2222%;
  --blot-top: 0%;
  --image-left: 29.6875%;
  --image-top: 0%;
  --blot-origin: 29.6875% 67.3653%;
}

.card-mask-ref-br {
  --ink: url("../assets/masks/reckon/bottom-right-ink.svg");
  --blot-width: 154.6667%;
  --blot-height: 142.6667%;
  --blot-left: 0%;
  --blot-top: 0%;
  --image-left: 0%;
  --image-top: 0%;
  --blot-origin: 64.655% 70.0932%;
}

.card-mask-ref-tl {
  --ink: url("../assets/masks/reckon/top-left-ink.svg");
  --blot-width: 145.3333%;
  --blot-height: 148.8889%;
  --blot-left: -45.3333%;
  --blot-top: -48.8889%;
  --image-left: 31.1927%;
  --image-top: 32.8358%;
  --blot-origin: 31.1927% 32.8358%;
}

.card-mask-ref-sr2 {
  --ink: url("../assets/masks/reckon/side-right2-ink.svg");
  --blot-width: 134.6667%;
  --blot-height: 121.3333%;
  --blot-left: 0%;
  --blot-top: 0%;
  --image-left: 0%;
  --image-top: 0%;
  --blot-origin: 74.2575% 41.2088%;
}

.card-mask-ref-sl2 {
  --ink: url("../assets/masks/reckon/side-left2-ink.svg");
  --blot-width: 142.2222%;
  --blot-height: 121.3333%;
  --blot-left: -42.2222%;
  --blot-top: 0%;
  --image-left: 29.6875%;
  --image-top: 0%;
  --blot-origin: 29.6875% 41.2088%;
}

.project-card:hover .card-image,
.project-card:hover .card-breakout-image,
.project-card:focus-visible .card-image,
.project-card:focus-visible .card-breakout-image {
  filter: saturate(1.08) contrast(1.02);
}

.project-card.is-placeholder .card-visual {
  color: var(--color-muted);
  font-size: var(--text-meta);
}

.card-meta {
  text-align: center;
  width: var(--card-size);
  margin-top: 12px;
}

.card-meta h3 {
  min-height: 14px;
  font-size: 10px;
  font-weight: 500;
  line-height: 14px;
}

.card-meta .card-note {
  display: block;
  min-height: 14px;
  overflow: hidden;
  color: rgba(26, 26, 26, 0.42);
  font-size: 10px;
  line-height: 14px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- 经历 / 教育 / 技能 ---------- */

/* 这三节整段居中：章节胶囊、标题、时间、正文、技能标签统一走中轴 */
#education,
#experience,
#skills {
  text-align: center;
}

.entry-list {
  display: grid;
  gap: var(--space-8);
  max-width: 780px;
  margin-inline: auto;
}

.entry {
  display: grid;
  gap: 0.3em;
  padding-bottom: var(--space-8);
  border-bottom: 1px solid var(--color-border-subtle);
}

.entry:last-child {
  border-bottom: none;
}

.entry-head {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.entry-head h3 {
  font-size: 1.15em;
  font-weight: 700;
}

.entry-head .entry-time {
  font-family: var(--font-mono);
  font-size: var(--text-meta);
  color: var(--color-muted);
  white-space: nowrap;
}

.entry .entry-role {
  font-size: var(--text-meta);
  color: var(--color-accent-warm);
  font-weight: 500;
}

/* 居中排版下项目符号会显得歪，改用纯文本分行 */
.entry ul {
  list-style: none;
  padding-left: 0;
  font-size: 0.95em;
  color: rgba(26, 26, 26, 0.82);
  display: grid;
  gap: 0.35em;
  margin-top: 0.4em;
  max-width: 62ch;
  margin-inline: auto;
}

/* ---------- 技能 ---------- */
.skills-cloud {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  max-width: 780px;
  margin-inline: auto;
}

.skill-tag {
  font-size: var(--text-meta);
  padding: 0.45em 1em;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  transition: transform var(--duration-fast) var(--ease-out-expo),
    background var(--duration-fast);
}

.skill-tag:hover {
  background: var(--color-accent);
  transform: translateY(-2px) rotate(-1deg);
}

.skill-group-label {
  width: 100%;
  font-size: var(--text-annotation);
  color: var(--color-faint);
  margin-top: var(--space-4);
}

/* ---------- 联系 ---------- */
.contact {
  padding-bottom: calc(var(--space-section) * 1.2);
}

.contact-title {
  font-size: var(--text-hero);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  max-width: 14em;
}

.contact-links {
  margin-top: var(--space-8);
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.contact-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  border: 1px solid var(--color-ink);
  border-radius: var(--radius-pill);
  padding: 0.6em 1.4em;
  font-size: var(--text-meta);
  font-weight: 500;
  transition: background var(--duration-fast), color var(--duration-fast),
    transform var(--duration-fast) var(--ease-out-expo);
}

.contact-chip:hover {
  background: var(--color-ink);
  color: var(--color-nav-fg);
  transform: translateY(-2px);
}

/* ---------- Dock 导航 ---------- */
.dock {
  position: fixed;
  bottom: max(env(safe-area-inset-bottom, 0px), 14px);
  left: 50%;
  translate: -50% 0;
  z-index: var(--z-dock);
  display: flex;
  align-items: flex-end;
  gap: 6px;
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--color-border);
  border-radius: 22px;
  padding: 8px;
  box-shadow: 0 12px 34px -14px rgba(26, 26, 26, 0.3);
}

.dock-item {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 14px;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border-subtle);
  position: relative;
  transition: transform var(--duration-fast) var(--ease-liquid),
    background var(--duration-fast);
}

.dock-item svg {
  width: 20px;
  height: 20px;
  stroke: var(--color-ink);
}

.dock-item:hover {
  transform: translateY(-8px) scale(1.12);
  background: var(--color-surface);
}

.dock-item.is-active {
  background: var(--color-ink);
}

.dock-item.is-active svg {
  stroke: var(--color-nav-fg);
}

/* dock tooltip */
.dock-item::after {
  content: attr(data-label);
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  translate: -50% 4px;
  font-size: var(--text-annotation);
  background: var(--color-ink);
  color: var(--color-nav-fg);
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--duration-fast), translate var(--duration-fast);
}

.dock-item:hover::after {
  opacity: 1;
  translate: -50% 0;
}

/* ---------- 小猫指针 ---------- */
.cat-cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-cursor);
  pointer-events: none;
  width: 30px;
  height: 30px;
  translate: -50% -55%;
  transition: transform 130ms var(--ease-out-expo), opacity 200ms ease;
}

.cat-cursor svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

.cat-cursor .cat-body {
  transform-origin: 50% 60%;
  transition: transform var(--duration-fast) var(--ease-liquid);
}

html.cursor-hovering .cat-cursor .cat-body {
  transform: scale(1.35) rotate(-8deg);
}

html.cursor-pressing .cat-cursor .cat-body {
  transform: scale(0.85) rotate(6deg);
}

@media (pointer: coarse) {
  .cat-cursor {
    display: none;
  }
}

/* ---------- 小猫吉祥物（作品网格里的符号位） ---------- */
.mascot-cell {
  display: grid;
  place-items: center;
  align-content: center;
  gap: var(--space-4);
  grid-column: 1 / -1;
  justify-self: center;
  width: 160px;
  text-align: center;
  aspect-ratio: 1 / 1;
}

.mascot {
  width: min(160px, 58%);
}

.mascot svg {
  width: 100%;
  height: auto;
  overflow: visible;
}

.mascot-cat {
  transform-origin: 50% 100%;
  transform-box: view-box;
  animation: mascot-hop 7s var(--ease-liquid) infinite;
}

.mascot-tail {
  transform-origin: 86px 96px;
  transform-box: view-box;
  animation: mascot-tail 3.2s ease-in-out infinite alternate;
}

.mascot-eye {
  transform-origin: center;
  transform-box: fill-box;
  animation: mascot-blink 4.4s infinite;
}

.mascot-eye:last-of-type {
  animation-delay: 0.06s;
}

@keyframes mascot-hop {
  0%, 74%, 100% { transform: translateY(0) scale(1, 1); }
  78%  { transform: translateY(0) scale(1.07, 0.9); }
  84%  { transform: translateY(-13px) scale(0.96, 1.06); }
  90%  { transform: translateY(0) scale(1.05, 0.94); }
  95%  { transform: translateY(0) scale(1, 1); }
}

@keyframes mascot-tail {
  from { transform: rotate(-6deg); }
  to   { transform: rotate(15deg); }
}

@keyframes mascot-blink {
  0%, 90%, 100% { transform: scaleY(1); }
  93%, 96% { transform: scaleY(0.06); }
}

/* ---------- Hero 联系行（可复制 + 跳转） ---------- */
.hero-contact {
  margin-top: var(--space-8);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.hero-contact .contact-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  padding: 0.5em 1em;
  font-size: var(--text-meta);
  font-weight: 500;
  color: var(--color-ink);
  background: var(--color-surface);
  cursor: pointer;
  transition: background var(--duration-fast), color var(--duration-fast),
    transform var(--duration-fast) var(--ease-out-expo),
    border-color var(--duration-fast);
}

.hero-contact .contact-chip:hover {
  background: var(--color-ink);
  color: var(--color-nav-fg);
  transform: translateY(-2px);
}

.hero-contact .contact-chip .ico {
  font-size: 0.95em;
  opacity: 0.75;
}

.hero-contact .contact-chip.is-link {
  border-color: var(--color-ink);
}

.copy-toast {
  position: fixed;
  left: 50%;
  bottom: 92px;
  translate: -50% 8px;
  background: var(--color-ink);
  color: var(--color-nav-fg);
  font-size: var(--text-meta);
  font-weight: 500;
  padding: 0.5em 1.1em;
  border-radius: var(--radius-pill);
  opacity: 0;
  pointer-events: none;
  z-index: var(--z-cursor);
  transition: opacity var(--duration-fast), translate var(--duration-fast);
}

.copy-toast.is-on {
  opacity: 1;
  translate: -50% 0;
}

/* ---------- 进场动效 ---------- */
.reveal {
  opacity: 0;
  translate: 0 26px;
  transition: opacity var(--duration-slow) var(--ease-out-expo),
    translate var(--duration-slow) var(--ease-out-expo);
}

.reveal.is-visible {
  opacity: 1;
  translate: 0 0;
}

/* ---------- 页面转场（View Transitions API）---------- */
@view-transition {
  navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.45s;
}

/* ---------- 语言切换的显隐 ---------- */
[data-lang-alt] {
  display: none;
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }

  .reveal {
    opacity: 1;
    translate: 0 0;
  }

  .bg-glyph {
    animation: none;
    transform: none;
    opacity: var(--galpha);
  }

  .bg-sketch,
  .mascot-cat,
  .mascot-tail,
  .mascot-eye,
  .cat-patrol-cat,
  .cat-patrol-cat img {
    animation: none;
  }

  .cat-patrol-cat {
    left: 50%;
    translate: -50% 0;
  }

  .card-cover-carousel {
    animation: none;
    opacity: 0;
    clip-path: none;
  }

  .card-cover-carousel:first-child {
    opacity: 1;
  }
}

/* ---------- 移动端 ---------- */
@media (max-width: 640px) {
  /* 小屏隐藏顶部状态 badge，避免面包屑换行 */
  .topbar .section-pill {
    display: none;
  }

  .work-groups {
    gap: var(--space-8);
    width: calc(100vw - 40px);
  }

  .work-group-head {
    margin-bottom: var(--space-4);
  }

  .cat-patrol {
    height: 76px;
  }

  .cat-patrol-cat {
    width: 76px;
  }

  .projects-grid {
    grid-template-columns: repeat(2, 130px);
    justify-content: space-between;
    column-gap: 0;
    row-gap: 36px;
  }

  .project-card {
    width: 130px;
    --card-size: 130px;
  }

  .mascot-cell {
    width: 130px;
  }

  .mascot {
    width: min(110px, 52%);
  }

  .dock {
    gap: 4px;
    padding: 6px;
  }

  .dock-item {
    width: 42px;
    height: 42px;
  }
}
