﻿/* ============================================================
   Candy Theme — interactions.css（交互增强层 · 2026-08-05）
   ============================================================
   覆盖范围：
   - A2 卡片微交互：hover 抬起 / 边框过渡 / 触摸波纹
   - A4 触屏友好：44px 最小触摸目标 / 移动端抽屉动画
   - A5 加载态增强：图片淡入 / spinner 统一 / 骨架屏
   - A6 焦点态与可访问性：focus-visible 环 / skip-link / reduced-motion

   加载序：紧跟 components.css 之后、responsive.css 之前
   铁律：全用 Token 变量，零硬编码颜色/尺寸/域名（守禁六）
   ============================================================ */

/* ============================================================
   A2：卡片微交互增强
   ============================================================ */

/* 卡片悬停抬升（覆盖 base.css 默认 .card:hover）
   注意：不得在此对 .card 加 will-change:transform —— 全站卡片数量大，
   永久合成层会导致 GPU 内存暴涨、滚动掉帧（#27 性能铁律）。
   仅保留 hover 过渡，浏览器在 hover 瞬间按需提升，足够流畅。 */
.card {
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              border-color 0.25s ease;
}
.card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-hover, 0 8px 30px rgba(28,27,25,.1));
  border-color: var(--gold);
}

/* 卡片内部图片缩放（配合 overflow:hidden） */
.card:hover .card-cover img {
  transform: scale(1.05);
}
.card-cover {
  overflow: hidden;
}
.card-cover img {
  transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

/* 卡片网格间距增强 */
.card-grid {
  gap: 24px;
}
.card-grid .card {
  height: 100%;
  display: flex;
  flex-direction: column;
}

/* 嵌入式卡片悬停增强 */
.embed-card {
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 0.25s ease,
              border-color 0.2s ease;
}
.embed-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md, 0 4px 12px rgba(28,27,25,.08));
}

/* ============================================================
   触摸波纹效果（ripple）
   ============================================================ */

.ripple-container {
  position: relative;
  overflow: hidden;
  /* 可选：由 JS 动态添加此类名 */
}

.ripple-effect {
  position: absolute;
  border-radius: 50%;
  background: rgba(var(--ink-rgb, 28,27,25), .12);
  transform: scale(0);
  animation: ripple-anim 0.6s ease-out forwards;
  pointer-events: none;
  z-index: 0;
}

@keyframes ripple-anim {
  to {
    transform: scale(4);
    opacity: 0;
  }
}

/* 移动端按钮按下反馈 */
@media (hover: none) and (pointer: coarse) {
  .btn:active,
  .card-act:active,
  .head-btn:active,
  .fa-btn:active {
    transform: scale(0.96);
    transition: transform 0.1s ease;
  }
}

/* ============================================================
   A4：触屏友好
   ============================================================ */

/* 44px 最小触摸目标（Apple HIG / WCAG 2.5.5） */
@media (hover: none) and (pointer: coarse) {
  .btn,
  .btn-sm,
  .btn-lg,
  .card-act,
  .head-btn,
  .fa-btn,
  .pagination a,
  .pagination .pager-arrow,
  .tag-chip,
  .nav-item,
  .nav-sub,
  .dropdown-item,
  input[type="checkbox"],
  input[type="radio"],
  .mb-item,
  .am-lb-nav,
  .tlm-vis-opt,
  .al-dp-item,
  .al-photo {
    min-height: 44px;
    min-width: 44px;
  }
  /* 紧密排列的按钮组增大间距防误触 */
  .card-acts {
    gap: 4px;
    padding: 4px 0;
  }
  .pagination {
    gap: 8px;
  }
  .pagination a,
  .pagination .pager-arrow {
    min-width: 44px;
    min-height: 44px;
    font-size: var(--font-size-sm);
  }
  /* 表单元素增大 */
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="search"],
  select,
  textarea {
    min-height: 44px;
    font-size: var(--fs-md); /* 防止 iOS 缩放 */
  }
}

/* 移动端抽屉滑入动画 */
.mobile-drawer {
  position: fixed;
  top: 0;
  left: 0;
  width: 280px;
  max-width: 85vw;
  height: 100vh;
  height: 100dvh;
  background: var(--bg);
  box-shadow: var(--shadow-lg, 0 0 40px rgba(28,27,25,.15));
  z-index: 1000;
  transform: translateX(-100%);
  transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.mobile-drawer.open {
  transform: translateX(0);
}

/* 抽屉遮罩 */
.drawer-mask {
  position: fixed;
  inset: 0;
  background: rgba(var(--ink-rgb, 28,27,25), .45);
  z-index: 999;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}

.drawer-mask.open {
  opacity: 1;
  visibility: visible;
}

/* ============================================================
   A5：加载态增强
   ============================================================ */

/* 图片默认可见（A5 图片淡入增强 · #27 性能铁律）
   此前实现为「全站 img 默认 opacity:0、加载后加 .loaded 才淡入」，
   列表页数十张图先空白再同时淡入，既造成空白/错位观感，又因大量 opacity
   过渡同时触发引发重绘卡顿。现改为图片随浏览器原生解码即时呈现，
   体验更跟手；局部确实需要淡入的组件自行加 .fade-in 类处理，不再全局隐藏。 */
img {
  opacity: 1;
}

/* 统一 Loading Spinner */
.spinner {
  display: inline-block;
  width: 24px;
  height: 24px;
  border: 2.5px solid var(--line);
  border-top-color: var(--gold);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

.spinner-sm {
  width: 16px;
  height: 16px;
  border-width: 2px;
}

.spinner-lg {
  width: 40px;
  height: 40px;
  border-width: 3px;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* 加载遮罩（全页/区段） */
.loading-overlay {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px 0;
  color: var(--muted);
  font-size: var(--fs-sm);
  gap: 10px;
}

/* ============================================================
   骨架屏基类（B1 骨骼屏前置基础）
   ============================================================ */

.skel {
  background: linear-gradient(
    90deg,
    var(--bg-soft, #f0ede6) 0%,
    var(--bg-deeper, #e8e4db) 40%,
    var(--bg-soft, #f0ede6) 80%
  );
  background-size: 200% 100%;
  animation: skel-shimmer 1.5s ease-in-out infinite;
  border-radius: var(--radius-sm, 6px);
  pointer-events: none;
  user-select: none;
  color: transparent !important;
}

@keyframes skel-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* 骨架屏变体 */
.skel-line {
  height: 14px;
  width: 100%;
  margin-bottom: 8px;
}
.skel-line:last-child { width: 60%; margin-bottom: 0; }

.skel-block {
  height: 120px;
  width: 100%;
}

.skel-circle {
  width: 48px;
  height: 48px;
  border-radius: 50%;
}

.skel-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
}

.skel-title {
  height: 20px;
  width: 75%;
  margin-bottom: 12px;
}

.skel-text {
  height: 13px;
  width: 100%;
  margin-bottom: 6px;
}
.skel-text:nth-child(3) { width: 85%; }
.skel-text:last-child  { width: 50%; margin-bottom: 0; }

/* 骨架卡片 */
.skel-card {
  padding: 16px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg, 12px);
}
.skel-card .skel-block {
  margin-bottom: 14px;
}

/* 骨架屏深色模式适配 */
[data-theme="dark"] .skel {
  background: linear-gradient(
    90deg,
    rgba(255,255,255,.04) 0%,
    rgba(255,255,255,.08) 40%,
    rgba(255,255,255,.04) 80%
  );
  background-size: 200% 100%;
}

/* ============================================================
   A6：焦点态与可访问性
   ============================================================ */

/* 统一焦点环（替 base.css .btn:focus-visible） */
:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: var(--radius-sm, 6px);
}

/* 输入框焦点光环 */
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px var(--gold-soft, rgba(169,133,74,.12));
}

/* 跳过导航链接 */
.skip-link {
  position: absolute;
  top: -100%;
  left: 16px;
  z-index: 99999;
  padding: 10px 20px;
  background: var(--gold);
  color: var(--bg);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  font-size: var(--font-size-sm);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  transition: top 0.2s ease;
}

.skip-link:focus {
  top: 0;
}

/* 减少动画偏好 */
@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;
  }

  .card:hover {
    transform: none;
  }

  .card-cover img {
    transition: none;
  }

  .skel {
    animation: none;
    background: var(--bg-soft);
  }
}

/* 高对比度模式 */
@media (prefers-contrast: high) {
  .card {
    border-width: 2px;
  }
  :focus-visible {
    outline-width: 3px;
  }
}

/* 色盲友好：链接下划线增强 */
@media (prefers-contrast: more) {
  a:not(.btn):not(.card-act):not(.head-btn):not(.fa-btn) {
    text-decoration: underline;
  }
}

/* ============================================================
   B2 空状态统一组件（前置基础样式）
   ============================================================ */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 24px;
  text-align: center;
  color: var(--muted);
}

.empty-state-icon {
  width: 64px;
  height: 64px;
  margin-bottom: 20px;
  color: var(--gold);
  opacity: 0.7;
}

.empty-state-icon svg {
  width: 100%;
  height: 100%;
}

.empty-state-title {
  font-family: var(--serif);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--ink);
  margin: 0 0 8px;
}

.empty-state-desc {
  font-size: var(--font-size-sm);
  color: var(--muted);
  max-width: 360px;
  line-height: 1.6;
  margin: 0 0 24px;
}

.empty-state-cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 24px;
  border-radius: var(--radius-pill);
  background: var(--gold);
  color: var(--bg);
  font-size: var(--font-size-sm);
  font-weight: var(--fw-medium);
  text-decoration: none;
  transition: background 0.2s ease, transform 0.2s ease;
}

.empty-state-cta:hover {
  background: var(--gold-hover);
  transform: translateY(-1px);
}

/* ============================================================
   B4 打印样式（前置基础）
   ============================================================ */

@media print {
  /* 隐藏交互元素 */
  .navbar,
  .mobile-bottom-nav,
  .back-to-top,
  .sidebar,
  .lightbox,
  .album-modal-overlay,
  .tl-modal-overlay,
  .drawer-mask,
  .mobile-drawer,
  .pb-edit-fab,
  .annotation-popup,
  .annotation-toolbar,
  .float-actions,
  .head-actions,
  .card-acts,
  .skip-link,
  .pagination,
  iframe,
  video,
  audio,
  .no-print {
    display: none !important;
  }

  /* 排版优化 */
  body {
    font-size: 12pt;
    line-height: 1.6;
    color: #000;
    background: #fff;
    max-width: 100%;
  }

  a {
    color: #000;
    text-decoration: underline;
  }

  /* 链接 URL 显示 */
  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 90%;
    color: #666;
  }

  /* 图片全宽 */
  img {
    max-width: 100% !important;
    page-break-inside: avoid;
    opacity: 1 !important;
  }

  /* 卡片打印优化 */
  .card {
    border: 1px solid #ccc;
    box-shadow: none;
    break-inside: avoid;
  }

  /* 分页控制 */
  h1, h2, h3, h4 {
    page-break-after: avoid;
  }

  p, li, blockquote {
    orphans: 3;
    widows: 3;
  }

  /* 容器全宽 */
  .container {
    max-width: 100% !important;
    padding: 0;
  }
}

/* ============================================================
   C1：页面过渡动画（View Transitions API）
   ============================================================ */

/* 页面过渡命名视图 */
::view-transition-old(root) {
  animation: 0.3s cubic-bezier(0.4, 0, 0.2, 1) both vt-fade-out;
}

::view-transition-new(root) {
  animation: 0.3s cubic-bezier(0.4, 0, 0.2, 1) both vt-fade-in;
}

@keyframes vt-fade-out {
  from { opacity: 1; }
  to { opacity: 0; transform: translateY(-8px); }
}

@keyframes vt-fade-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* 滚动渐显动画 */
.reveal-on-scroll {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s cubic-bezier(0.4, 0, 0.2, 1),
              transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}

.reveal-on-scroll.revealed {
  opacity: 1;
  transform: translateY(0);
}

/* C2 手势滑动容器 */
.swipe-container {
  touch-action: pan-y;
  user-select: none;
}

/* ============================================================
   C3：下拉刷新
   ============================================================ */

.ptr-indicator {
  width: 100%;
  height: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  opacity: 0;
  transition: height 0.3s ease, opacity 0.3s ease;
}

.ptr-indicator.ptr-ready .ptr-spinner {
  border-color: var(--gold);
  animation: ptr-pulse 0.6s ease-in-out infinite;
}

.ptr-indicator.ptr-refreshing .ptr-spinner {
  border-top-color: var(--gold);
  animation: spin 0.7s linear infinite;
}

.ptr-spinner {
  width: 28px;
  height: 28px;
  border: 2.5px solid var(--line);
  border-top-color: transparent;
  border-radius: 50%;
}

@keyframes ptr-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.15); }
}

/* ============================================================
   A7：软导航（View Transitions）进度反馈 + 链接态
   修复「点击无反应/卡住/过一会才跳」：点击即显示顶部进度条，
   页面不再被 VT 覆盖伪元素长时间冻结；8s 超时由 JS 兜底真实跳转。
   组件取 Token 变量，零硬编码颜色/尺寸（守禁六）。
   ============================================================ */
.nav-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 0;
  z-index: 99999;
  background: var(--gold, #b88a2d);
  box-shadow: 0 0 8px var(--gold, #b88a2d);
  opacity: 0;
  transition: width 0.3s ease, opacity 0.2s ease;
  pointer-events: none;
}
.nav-progress.active {
  opacity: 1;
  width: 75%;
  /* 缓动到 75% 表示加载中，剩余 25% 在换页完成时收尾 */
  animation: nav-progress-indeterminate 1.2s ease-in-out infinite alternate;
}
@keyframes nav-progress-indeterminate {
  from { width: 20%; }
  to { width: 80%; }
}

/* 软导航进行中：给被点链接一个轻微态，强化「已点击」反馈 */
a.nav-pending {
  opacity: 0.6;
  transition: opacity 0.15s ease;
}

/* 尊重 reduced-motion：禁用进度条动画与 VT 抖动 */
@media (prefers-reduced-motion: reduce) {
  .nav-progress.active { animation: none; width: 75%; }
}
