/* ============================================
   PersonalWeb - Minimal B&W Design System
   Inspira UI inspired, B&W color palette
   ============================================ */

/* ---------- CSS Variables ---------- */
:root {
  color-scheme: dark;
  --bg-primary: #0a0a0a;
  --bg-secondary: #111111;
  --bg-card: #1a1a1a;
  --bg-card-hover: #222222;
  --text-primary: #faf9f5;
  --text-secondary: #a3a3a3;
  --text-muted: #666666;
  --accent: #ffffff;
  --accent-subtle: rgba(255,255,255,0.08);
  --border: rgba(255,255,255,0.08);
  --border-hover: rgba(255,255,255,0.18);
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
  --transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  --transition-fast: 0.15s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ---------- Reset & Base ---------- */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

html {
  -webkit-font-smoothing: antialiased;
}

body {
  font-family: var(--font-sans);
  background: var(--bg-primary);
  color: var(--text-primary);
  line-height: 1.6;
  overflow-x: hidden;
}

a { color: var(--text-primary); text-decoration: none; transition: color var(--transition); }
a:hover { color: var(--accent); }
img { max-width: 100%; display: block; }
button { font-family: inherit; }

/* ---------- Navigation ---------- */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  padding: 20px clamp(32px, 5vw, 80px);
  transition: background var(--transition), padding var(--transition);
}
.nav.scrolled {
  background: rgba(10,10,10,0.92);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  padding: 14px clamp(32px, 5vw, 80px); /* match nav horizontal */
  border-bottom: 1px solid var(--border);
}
.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.nav-logo {
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  display: inline-flex;
  align-items: baseline;
  white-space: nowrap;
}
/* Anthropic-style expand: R + C stay, "Ray Chan" reveals on hover
 * Elegant: expand in order, collapse in REVERSE order.
 * Collapse has a 220ms grace period before starting (avoids urgency on quick mouse-leave).
 */
.nav-logo-c,
.nav-logo-r {
  display: inline-block;
  transition: color 0.3s;
}
.nav-logo-expand,
.nav-logo-expand2 {
  display: inline-block;
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  vertical-align: baseline;
  opacity: 0;
  /* Fast layout snap + smooth GPU visual */
  transition: max-width 0.15s ease 0s,
              clip-path 0.55s cubic-bezier(0.22, 1, 0.36, 1) 0s,
              opacity 0.4s ease 0s;
  clip-path: inset(0 100% 0 0);
  margin: 0;
  padding: 0;
}
/* Collapse stagger: reverse — first expand2 closes, then expand */
.nav-logo-expand  {
  transition: max-width 0.15s ease 0s,
              clip-path 0.55s cubic-bezier(0.22, 1, 0.36, 1) 0s,
              opacity 0.4s ease 0s;
}

/* Expand: no grace, instant start, staggered — herish first, emain second */
.nav-logo:hover .nav-logo-expand {
  max-width: 140px;
  clip-path: inset(0 0% 0 0);
  opacity: 1;
  transition: max-width 0.15s ease 0s,
              clip-path 0.65s cubic-bezier(0.22, 1, 0.36, 1) 0s,
              opacity 0.4s ease 0s;
}
.nav-logo:hover .nav-logo-expand2 {
  max-width: 140px;
  clip-path: inset(0 0% 0 0);
  opacity: 1;
  transition: max-width 0.15s ease 0s,
              clip-path 0.65s cubic-bezier(0.22, 1, 0.36, 1) 0.12s,
              opacity 0.4s ease 0.12s;
}

/* Grace period on collapse — 220ms delay before starting */
.nav-logo:not(:hover) .nav-logo-expand,
.nav-logo:not(:hover) .nav-logo-expand2 {
  transition: max-width 0.15s ease 0.22s,
              clip-path 0.55s cubic-bezier(0.4, 0, 0.2, 1) 0.22s,
              opacity 0.4s ease 0.22s;
}
.nav-logo:not(:hover) .nav-logo-expand2 {
  transition: max-width 0.15s ease 0.22s,
              clip-path 0.55s cubic-bezier(0.4, 0, 0.2, 1) 0.22s,
              opacity 0.4s ease 0.22s;
}
.nav-logo:not(:hover) .nav-logo-expand {
  transition: max-width 0.15s ease 0.32s,
              clip-path 0.55s cubic-bezier(0.4, 0, 0.2, 1) 0.32s,
              opacity 0.4s ease 0.32s;
}

.nav-links { display: flex; gap: 32px; }
.nav-link {
  font-size: 0.85rem;
  font-weight: 400;
  color: var(--text-secondary);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  position: relative;
}
.nav-link::after {
  content: '';
  position: absolute;
  bottom: -4px; left: 0;
  width: 0; height: 1px;
  background: #fff;
  transition: width var(--transition);
}
.nav-link:hover { color: var(--text-primary); }
.nav-link:hover::after { width: 100%; }

.nav-mobile-btn {
  display: none;
  background: none;
  border: none;
  width: 28px; height: 20px;
  position: relative;
}
.nav-mobile-btn span {
  display: block;
  width: 100%; height: 1.5px;
  background: var(--text-primary);
  position: absolute;
  left: 0;
  transition: transform var(--transition), background var(--transition);
}
.nav-mobile-btn span:first-child { top: 0; }
.nav-mobile-btn span:last-child { bottom: 0; }
.nav-mobile-btn.active span:first-child { top: 50%; transform: translateY(-50%) rotate(45deg); }
.nav-mobile-btn.active span:last-child { bottom: 50%; transform: translateY(50%) rotate(-45deg); }

/* Search entry — pill button aligned with nav links; ⌘K hint on desktop */
.nav-right { display: flex; align-items: center; gap: 28px; }
@media (max-width: 768px) {
  .nav-links {
    display: flex;
    position: absolute;
    top: 100%; left: 0; right: 0;
    background: rgba(10,10,10,0.97);
    backdrop-filter: blur(12px);
    padding: 24px 40px;
    gap: 20px;
    border-bottom: 1px solid var(--border);
    flex-direction: column;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition: opacity 0.25s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.25s cubic-bezier(0.16, 1, 0.3, 1),
                visibility 0s linear 0.25s;
  }
  .nav-links.open {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition: opacity 0.25s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.25s cubic-bezier(0.16, 1, 0.3, 1),
                visibility 0s linear 0s;
    z-index: 60;
  }
  .nav-mobile-btn { display: block; }
  .nav { padding: 16px 24px; }
  .nav.scrolled { padding: 12px 24px; }
  .nav-right { gap: 14px; }
}

/* ---------- Hero ---------- */
.hero {
  min-height: 100vh;
  display: flex;
  align-items: center;
  position: relative;
  z-index: 1;
  overflow: hidden;
}

/* 满屏背景图 */
.hero-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.hero-bg-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 95% center;
}

/* 移动端：背景图居中显示 */
@media (max-width: 768px) {
  .hero-bg-img {
    object-position: 50% center;
  }
}

/* 左侧深色渐变遮罩 — 从左到右逐渐透明 */
.hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    to right,
    rgba(10, 10, 10, 0.97) 0%,
    rgba(10, 10, 10, 0.94) 25%,
    rgba(10, 10, 10, 0.82) 45%,
    rgba(10, 10, 10, 0.55) 62%,
    rgba(10, 10, 10, 0.25) 78%,
    transparent 100%
  );
}

/* 底部淡化过渡 — Hero 图片自然溶解到下一模块的深色背景 */
.hero::after {
  content: '';
  position: absolute;
  bottom: 0; left: 0; right: 0;
  height: 35%;
  z-index: 1;
  background: linear-gradient(
    to bottom,
    transparent 0%,
    rgba(10, 10, 10, 0.25) 30%,
    rgba(10, 10, 10, 0.65) 60%,
    rgba(10, 10, 10, 0.9) 80%,
    var(--bg-primary) 100%
  );
  pointer-events: none;
}

/* 内容容器 */
.hero-content {
  position: relative;
  z-index: 2;
  width: 100%;
  /* Left-align with nav logo — same horizontal padding */
  padding: 120px clamp(32px, 5vw, 80px) 80px clamp(32px, 5vw, 80px);
}
.hero-text { max-width: 520px; }
.hero-name {
  margin-bottom: 28px;
  white-space: nowrap;
  /* NO animation on container — avoid double opacity compositing */
}
.hero-name-line {
  display: inline-block;
  font-size: clamp(3.5rem, 8vw, 6.5rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.05;
  color: #f5f5f5;
  opacity: 0;
  /* Use translate3d to force GPU compositing layer unconditionally */
  transform: translate3d(0, 18px, 0);
  transition:
    opacity   1.1s cubic-bezier(0.22, 1, 0.36, 1),
    transform 1.1s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform, opacity;
  /* Force own compositing layer — prevent repaint on every frame */
  z-index: 1;
  position: relative;
}
.hero-name-accent { color: var(--text-muted); }
.hero-name-line + .hero-name-line { margin-left: 0.12em; }

.hero-tagline {
  font-size: 1.2rem;
  color: var(--text-secondary);
  margin-bottom: 40px;
  line-height: 1.7;
  max-width: 400px;
}

/* 打字机光标：跟随当前正在输入的行 */
.hero-tagline-line.typing::after {
  content: '|';
  display: inline-block;
  margin-left: 2px;
  animation: cursor-blink 0.85s step-end infinite;
  font-weight: 300;
  color: var(--text-secondary);
}
.hero-tagline-line {
  display: inline;
}
@keyframes cursor-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0; }
}

/* ---------- Hero Entrance Animation ---------- */
/* Only .hero-name-line animates (opacity + translate3d).
   NO animation on .hero-name container — avoids double compositing. */
.hero-text > .hero-tagline,
.hero-text > .hero-cta {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition:
    opacity   1.0s cubic-bezier(0.22, 1, 0.36, 1),
    transform 1.0s cubic-bezier(0.22, 1, 0.36, 1);
}
/* .hero-name: static container, no animation at all */
.hero-text > .hero-name {
  opacity: 0;
}
/* Fade in container immediately (no transform), then name lines stagger */
.hero-text.hero-loaded > .hero-name    { opacity: 1; }
.hero-text.hero-loaded > .hero-tagline { opacity: 1; transform: translate3d(0, 0, 0); transition-delay: 1.50s; }
.hero-text.hero-loaded > .hero-cta     { opacity: 1; transform: translate3d(0, 0, 0); transition-delay: 2.00s; }
/* Name lines: each word fades in on its own compositing layer */
.hero-text.hero-loaded .hero-name-line:nth-child(1) { opacity: 1; transform: translate3d(0, 0, 0); transition-delay: 0.50s; }
.hero-text.hero-loaded .hero-name-line:nth-child(2) { opacity: 1; transform: translate3d(0, 0, 0); transition-delay: 0.90s; }

/* ============================================
   Buttons — Subtle Hint
   ============================================ */

.btn-magnetic {
  display: inline-block;
  transform: translate(var(--mx, 0px), var(--my, 0px));
  transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  will-change: transform;
}
.btn-magnetic.is-magnetic {
  transition: transform 0.12s cubic-bezier(0.4, 0, 0.2, 1);
}

.btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 4px;
  font-size: 0.72rem;
  font-weight: 300;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--text-muted);
  background: transparent;
  border: none;
  transition: color 0.4s ease;
  position: relative;
}

/* 底部细线 —— hover 时从中心展开 */
.btn-primary::after {
  content: '';
  position: absolute;
  bottom: 2px; left: 50%;
  width: 0; height: 1px;
  background: var(--text-secondary);
  transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  transform: translateX(-50%);
}
.btn-primary:hover {
  color: var(--text-secondary);
}
.btn-primary:hover::after {
  width: 100%;
}

/* 箭头轻微呼吸弹跳 */
.btn-arrow {
  display: inline-block;
  animation: arrow-breathe 2.4s ease-in-out infinite;
  font-size: 0.95em;
}
@keyframes arrow-breathe {
  0%, 100% { transform: translateY(0); opacity: 0.5; }
  50%      { transform: translateY(4px); opacity: 1; }
}

@media (max-width: 768px) {
  .hero { padding: 100px 5vw 60px; }
  .hero-content { padding: 80px clamp(16px,3vw,28px) 40px; }
  .hero-text { max-width: 100%; margin: 0 auto; text-align: center; }
  .hero-tagline { margin: 0 auto 32px; }
  /* 移动端：渐变更深，覆盖更多背景图 */
  .hero-overlay {
    background: linear-gradient(
      to right,
      rgba(10, 10, 10, 0.97) 0%,
      rgba(10, 10, 10, 0.92) 50%,
      rgba(10, 10, 10, 0.75) 80%,
      rgba(10, 10, 10, 0.4) 100%
    );
  }
}

/* ---------- Sections ---------- */
.section {
  padding: 120px 40px;
  position: relative;
  z-index: 1;
}
.section-dark { background: var(--bg-secondary); }

/* About Me — soft aurora glow so the near-black section gains depth (Option A).
   Base stays --bg-primary; two faint radial blooms (indigo + violet) lift it
   without breaking the dark, premium tone. No layout/HTML change. */
#about {
  background:
    radial-gradient(64% 54% at 32% 38%, rgba(99, 102, 241, 0.11), transparent 72%),
    radial-gradient(50% 48% at 80% 46%, rgba(139, 92, 246, 0.07), transparent 72%),
    var(--bg-primary);
}

.container { max-width: 1200px; margin: 0 auto; }

.section-header { margin-bottom: 64px; }
.section-number {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--text-muted);
  letter-spacing: 0.12em;
  display: block;
  margin-bottom: 12px;
}
.section-title {
  font-size: clamp(1.8rem, 4vw, 2.8rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: #f5f5f5;
}
.section-line {
  width: 40px; height: 1px;
  background: var(--text-muted);
  margin-top: 20px;
}

/* ---------- About ---------- */
.about-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 80px;
  align-items: start;
}
.about-text { max-width: none; }
.about-bio {
  font-size: 1rem;
  line-height: 1.75;
  color: var(--text-primary);
  margin-bottom: 18px;
  letter-spacing: 0.04em;
  font-family: var(--font-mono);
}
.about-tags { display: flex; flex-wrap: wrap; gap: 10px; }
.tag {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text-secondary);
  border: 1px solid var(--border);
  padding: 6px 16px;
  letter-spacing: 0.04em;
  transition: border-color var(--transition), color var(--transition), background var(--transition);
}
.tag:hover {
  border-color: var(--border-hover);
  color: var(--text-primary);
  background: var(--accent-subtle);
}

/* 方案B：About 区职业标签去边框，融入纯文本信息流 */
.about-tags .tag {
  font-size: 0.85rem;
  border: none;
  padding: 0;
  background: none;
}
.about-tags .tag:hover {
  border: none;
  background: none;
  color: var(--text-primary);
}

/* 左侧当前关注 — 方案B：纯文本信息流，无边框无横线 */
.about-focus {
  margin-top: 22px;
  padding-top: 0;
  border-top: none;
  font-size: 0;
}
.about-focus-label {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--text-muted);
  letter-spacing: 0.04em;
  text-transform: none;
  display: inline;
}
.about-focus-label::after {
  content: ": ";
}
.about-focus-text {
  display: inline;
  font-size: 0.85rem;
  color: var(--text-secondary);
  line-height: 1.7;
}

/* 右侧经历时间线 — 整体往上移，与左侧 bio 顶部对齐 */
.about-experience { position: relative; margin-top: -18px; }
.timeline {
  display: flex;
  flex-direction: column;
  gap: 0;
  position: relative;
  padding-left: 24px;
}
.timeline::before {
  content: '';
  position: absolute;
  left: 3px;
  top: 0;
  bottom: 6px;
  width: 1px;
  background: var(--border);
}
.timeline-item {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 0 20px 20px;
  position: relative;
  border-bottom: 1px solid var(--border);
}
.timeline-item:last-child { border-bottom: none; }
.timeline-item::before {
  content: '';
  position: absolute;
  left: -24px;
  top: 18px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--text-muted);
  border: 1.5px solid var(--bg-primary);
  z-index: 1;
}
.timeline-item--current::before {
  background: #fff;
  box-shadow: 0 0 0 3px rgba(255,255,255,0.15);
}
.timeline-year {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--text-muted);
  letter-spacing: 0.10em;
  text-transform: uppercase;
}
.timeline-logo {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--text-primary);
  letter-spacing: 0.02em;
}
.timeline-role {
  font-size: 0.82rem;
  color: var(--text-secondary);
}

@media (max-width: 768px) {
  .section { padding: 80px 24px; }
  .about-layout {
    grid-template-columns: 1fr;
    gap: 48px;
  }
}

/* ---------- Contact ---------- */
.contact-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin-bottom: 48px;
}
.contact-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 28px 24px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  transition: border-color var(--transition), background var(--transition), transform var(--transition);
  cursor: pointer;
  overflow: hidden;
}
.contact-card:hover {
  border-color: var(--border-hover);
  background: var(--bg-card-hover);
  transform: translateY(-2px);
}

/* Subtle "copy" hint — driven by JS (.show reveals, .success turns green)
   so the success confirmation never flips back to the hover hint. */
.copy-hint {
  position: absolute;
  top: 14px;
  right: 14px;
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.05em;
  color: rgba(255,255,255,0.3);
  padding: 3px 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.25s ease, transform 0.25s ease, color 0.25s ease, border-color 0.25s ease;
  pointer-events: none;
}
.copy-hint.show {
  opacity: 1;
  transform: translateY(0);
  color: rgba(255,255,255,0.38);
  border-color: var(--border-hover);
}
.copy-hint.success {
  color: rgba(140, 200, 160, 0.85);
  border-color: rgba(140, 200, 160, 0.4);
}

.contact-icon {
  flex-shrink: 0;
  width: 44px; height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.contact-icon svg {
  width: 24px; height: 24px;
  fill: none;
  stroke: var(--text-muted);
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: stroke 0.3s ease, transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.contact-card:hover .contact-icon svg { stroke: var(--text-secondary); }
.contact-card:hover .contact-icon--mail svg  { transform: translateY(-2px) rotate(-4deg); }
.contact-card:hover .contact-icon--phone svg { transform: rotate(-12deg); }
.contact-card:hover .contact-icon--pin svg   { transform: translateY(2px); }
.contact-card h4 {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--text-secondary);
  margin-bottom: 4px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.contact-card p {
  font-size: 0.9rem;
  color: var(--text-primary);
}

/* contact-card 铅笔手绘背景变体（花 / 叶子 / 藤蔓） */
.contact-card::before {
  content: "";
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  filter: grayscale(1) contrast(1.05);
  opacity: 0.12;
  pointer-events: none;
  z-index: 0;
  transition: filter 0.45s ease, opacity 0.45s ease;
  /* 右下角水印区域渐隐（135deg 末端落在右下） */
  -webkit-mask-image: linear-gradient(135deg, #000 66%, transparent 100%);
          mask-image: linear-gradient(135deg, #000 66%, transparent 100%);
}
.contact-card > * { position: relative; z-index: 1; }
.contact-card > .copy-hint { position: absolute; }

.contact-card--flower::before { background-image: url("/assets/contact/flower.jpg"); }
.contact-card--leaf::before   { background-image: url("/assets/contact/leaf.jpg"); background-position: center 55%; }
.contact-card--vine::before   { background-image: url("/assets/contact/vine.jpg"); opacity: 0.16; }

/* Hover lights up the pencil sketch without washing out the strokes.
   The sketch is light-gray lines on near-white paper, so a raw brightness()
   boost lifts the lines toward the paper and kills the texture. Instead we
   raise opacity (lines read brighter over the dark card) and contrast (keeps
   the strokes crisp), with only a faint brightness lift for a "wake" feel. */
.contact-card:hover::before {
  filter: grayscale(1) contrast(1.32) brightness(1.05);
  opacity: 0.3;
}

.social-links { display: flex; gap: 16px; flex-wrap: wrap; }
.social-link {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--text-secondary);
  border: 1px solid var(--border);
  padding: 10px 24px;
  letter-spacing: 0.04em;
  transition: border-color var(--transition), color var(--transition), background var(--transition);
}
.social-link:hover {
  border-color: var(--border-hover);
  color: var(--text-primary);
  background: var(--accent-subtle);
}

@media (max-width: 768px) {
  .contact-grid { grid-template-columns: 1fr; }
}

/* ---------- Footer ---------- */
.footer {
  padding: 52px 40px;
  border-top: 1px solid var(--border);
  position: relative;
  z-index: 1;
}
.footer .container {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-align: center;
}
/* Letter-style signature: an elegant italic serif sign-off above a quiet
   mono caption — reads like the closing line of a personal letter. */
.footer-sign {
  font-family: 'Georgia', 'Times New Roman', 'Songti SC', serif;
  font-style: italic;
  font-size: 1.05rem;
  color: var(--text-secondary);
  letter-spacing: 0.01em;
  transition: color var(--transition);
}
.footer-sign:hover {
  color: var(--text-primary);
}
.footer-sign-sub {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--text-muted);
  letter-spacing: 0.06em;
}
.footer-sign-sub a {
  color: var(--text-secondary);
  text-decoration: none;
  transition: color var(--transition);
  border-bottom: 1px solid transparent;
}
.footer-sign-sub a:hover {
  color: var(--text-primary);
  border-bottom-color: var(--border-hover);
}

@media (max-width: 768px) {
  .footer { padding: 40px 24px; }
}

/* ---------- Scroll Animations ---------- */
/* Premium easing: fast start, slow end — intentional, not bouncy */
.animate-on-scroll {
  opacity: 0;
  transform: translateY(32px);
  transition:
    opacity 0.85s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.85s cubic-bezier(0.16, 1, 0.3, 1);
}
.animate-on-scroll.visible {
  opacity: 1;
  transform: translateY(0);
}

/* Stagger children inside .section-header */
.section-header.animate-on-scroll .section-number { transition-delay: 0s; }
.section-header.animate-on-scroll .section-title  { transition-delay: 0.1s; }
.section-header.animate-on-scroll .section-line    { transition-delay: 0.2s; }

/* Children start hidden, reveal when parent gets .visible */
.section-header.animate-on-scroll .section-number,
.section-header.animate-on-scroll .section-title,
.section-header.animate-on-scroll .section-line {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
.section-header.animate-on-scroll.visible .section-number,
.section-header.animate-on-scroll.visible .section-title,
.section-header.animate-on-scroll.visible .section-line {
  opacity: 1;
  transform: translateY(0);
}

/* ---------- Selection ---------- */
::selection {
  background: rgba(255,255,255,0.15);
  color: #fff;
}

/* ---------- Focus Visible (keyboard navigation) ---------- */
:focus-visible {
  outline: 2px solid rgba(255,255,255,0.4);
  outline-offset: 2px;
  border-radius: 2px;
}
/* Remove outline for mouse clicks on elements that already have visual feedback */
:focus:not(:focus-visible) { outline: none; }

/* ---------- Reduced Motion (accessibility) ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  body { cursor: auto !important; }
  button, a { cursor: pointer !important; }
  .animate-on-scroll {
    opacity: 1 !important;
    transform: none !important;
  }
  .hero-text > * {
    opacity: 1 !important;
    transform: none !important;
  }
  .hero-name-line {
    opacity: 1 !important;
    transform: none !important;
  }
  .hero-name { white-space: normal; }
}

/* ---------- Back to Top Button (icon only, no container) ---------- */
.back-to-top {
  position: fixed;
  bottom: 26px;
  right: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  background: transparent;
  border: none;
  color: rgba(255, 255, 255, 0.45);
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  transition: color 0.3s ease, opacity 0.35s cubic-bezier(0.16, 1, 0.3, 1), transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
  z-index: 90;
  pointer-events: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.back-to-top.visible {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  pointer-events: auto;
}

.back-to-top:hover,
.back-to-top:focus-visible {
  color: rgba(255, 255, 255, 1);
}

.back-to-top svg {
  transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

.back-to-top:hover svg {
  transform: translateY(-2px);
}

@media (max-width: 768px) {
  .back-to-top {
    bottom: 18px;
    right: 18px;
    padding: 2px;
  }
}

/* ============================================
   Page Transition Overlay
   ============================================ */
.page-transition-overlay {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: #0a0a0a;
  pointer-events: none;
  opacity: 0;
}

/* ============================================
   Toast — click-to-copy feedback (Contact cards)
   ============================================ */
.ray-toast {
  position: fixed;
  top: 24px;
  left: 50%;
  transform: translate(-50%, -16px);
  padding: 12px 22px;
  font-family: var(--font-sans);
  font-size: 0.85rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.9);
  background: rgba(22, 22, 24, 0.82);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 999px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(14px) saturate(180%);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
  z-index: 100000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.ray-toast::before {
  content: '✓';
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  background: rgba(255, 255, 255, 0.14);
  color: #fafafa;
  border-radius: 50%;
  font-size: 0.7rem;
}
.ray-toast.show {
  opacity: 1;
  transform: translate(-50%, 0);
}
@media (max-width: 768px) {
  .ray-toast {
    top: 16px;
    padding: 10px 18px;
    font-size: 0.8rem;
  }
}

/* ============================================
   Shared Hero Background Effect (essays & photos reuse this)
   mask 椭圆尺寸由各自页面覆盖（photos 用更宽椭圆）
   ============================================ */
.hero-bg-effect {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  mask-image: radial-gradient(ellipse 2800px 1600px at 50% 50%, white 0%, transparent 99%);
  -webkit-mask-image: radial-gradient(ellipse 2800px 1600px at 50% 50%, white 0%, transparent 99%);
}
.hero-bg-effect::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 50% 60% at 50% 50%, rgba(255,255,255,0.03), transparent 70%);
  pointer-events: none;
}
.hero-glow-line {
  position: absolute;
  top: 0;
  height: 1px;
  border-radius: 1px;
  animation: glow-pulse 4s ease-in-out infinite alternate;
}
.hero-glow-line--indigo { left: 20%; width: 55%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.5), transparent); }
.hero-glow-line--indigo-blur { left: 20%; width: 55%; height: 3px; filter: blur(8px); background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); }
.hero-glow-line--sky { left: 55%; width: 30%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent); }
.hero-glow-line--sky-blur { left: 55%; width: 30%; height: 4px; filter: blur(10px); background: linear-gradient(90deg, transparent, rgba(255,255,255,0.25), transparent); }
.hero-glow-line--indigo-blur, .hero-glow-line--sky-blur { animation-delay: 0.8s; }
@keyframes glow-pulse { 0% { opacity: 0.5; } 100% { opacity: 1; } }
#hero-sparkle-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }

