@charset "UTF-8";
/* ============================================================
   lightbox.css · 自研灯箱
   归属：engineer-ui（独占）。只引用 tokens.css 的变量，不重定义。
   移动端优先：默认即移动端样式，min-width 查询只做增强。

   契约 v2.1 已禁止一切 CDN 外链（含 Fancybox），全站只用
   assets/js/lightbox.js 这一套自研实现，因此本文件不含任何第三方主题覆盖。

   选择器严格对齐 assets/js/lightbox.js 的真实输出（已逐行核对
   buildOverlay / renderCurrent / updateChrome），不是契约草稿里的形状：

     #lightbox-host.lightbox-host[.lb-host--open]
       .lb[.is-open][.lb--zoomed]        role=dialog aria-modal
         .lb__backdrop                   遮罩层（点击关闭）
         figure.lb__stage                舞台，内含下列之一：
           img.lb__media.lb__media--image
           video.lb__media.lb__media--video
           .lb__placeholder > img.lb__placeholder-img + span.lb__placeholder-hint
         .lb__bar.glass                  液态玻璃操作条
           button.lb__btn.lb__btn--prev  ‹
           span.lb__counter              3 / 12
           button.lb__btn.lb__btn--next  ›
           button.lb__btn.lb__btn--zoom  ＋
           button.lb__btn.lb__btn--close ✕
         p.lb__caption                   （无文字时带 hidden）
         p.lb__hint                      ← → 提示
     JS 还会给 <html>/<body> 加 .lb-locked（并自行固定 body）

   注意：操作条带 .glass，其玻璃底色/描边/内发光由 glass.css 负责，
   这里只补布局与按钮形态，避免与 designer 的材质体系打架。
   ============================================================ */

/* ---------- 1. 宿主 ---------- */

/* 关闭时 JS 设 host.hidden = true，base.css 的 [hidden] 已能隐藏；
   打开时 host 只是一层定位容器，遮罩本身是 fixed 全屏。
   这里不写 display:contents —— 它会让某些浏览器对含 fixed 子元素的
   包含块判定变得难以预测，保留普通块级更稳。 */
.lightbox-host {
  position: relative;
  z-index: var(--z-lightbox);
}

/* ---------- 2. 遮罩层 ---------- */

.lb {
  position: fixed;
  inset: 0;
  z-index: var(--z-lightbox);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  box-sizing: border-box;
  /* 避开刘海与底部指示条 */
  padding:
    calc(var(--safe-top) + var(--sp-3))
    calc(var(--safe-right) + var(--sp-3))
    calc(var(--safe-bottom) + var(--sp-3))
    calc(var(--safe-left) + var(--sp-3));
  color: var(--c-cream-50);
  font-family: var(--ff-body);
  opacity: 0;
  visibility: hidden;
  /* 关闭：更快（--dur-fast），并让 visibility 等淡出结束再切 */
  transition:
    opacity var(--dur-fast) var(--ease-out-soft),
    visibility 0s linear var(--dur-fast);
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: contain;
  /* 舞台内自己做手势，遮罩层只允许纵向滚动与缩放 */
  touch-action: pan-y pinch-zoom;
}

.lb.is-open {
  opacity: 1;
  visibility: visible;
  transition:
    opacity var(--dur-base) var(--ease-out-soft),
    visibility 0s linear 0s;
}

/* 遮罩背景层：深色半透明 + 毛玻璃，绝对定位铺满 */
.lb__backdrop {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--c-ink-900) 84%, transparent);
  backdrop-filter: blur(var(--blur-lg)) saturate(120%);
  -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(120%);
}

/* ---------- 3. 舞台与媒体 ---------- */

.lb__stage {
  position: relative;
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  /* min-height/min-width:0 是让子元素 max-height:100% 真正生效的关键 */
  min-width: 0;
  min-height: 0;
  margin: 0;
  padding-block: var(--sp-2);
}

.lb__media {
  display: block;
  box-sizing: border-box;
  max-width: 100%;
  max-height: 100%;
  border-radius: var(--r-lg);
  background: var(--glass-bg);
  box-shadow:
    inset 0 0 0 1px var(--glass-inner-glow),
    0 24px 60px color-mix(in srgb, var(--c-ink-900) 55%, transparent);
  object-fit: contain;
  /* 打开动画起点：稍小一点，配合 --ease-spring 弹出 */
  opacity: 0;
  transform: scale(0.92);
  transition:
    opacity var(--dur-base) var(--ease-out-soft),
    transform var(--dur-base) var(--ease-spring);
}

.lb.is-open .lb__media {
  opacity: 1;
  transform: scale(1);
}

/* 视频自带黑边与控件，去掉圆角底色避免边缘露出一圈玻璃色 */
.lb__media--video {
  border-radius: var(--r-md);
  background: transparent;
}

/* 放大状态：媒体按原始尺寸显示并允许拖拽查看 */
.lb--zoomed .lb__media {
  max-width: none;
  max-height: none;
  cursor: grab;
}

/* ---------- 4. 素材待补占位卡 ---------- */

.lb__placeholder {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
  max-height: 100%;
  /* 兜底高度：占位图尚未解码或解码失败时也不能塌成一条线，
     否则灯箱里会出现「什么都没有」的空洞 */
  min-height: 44svh;
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--glass-bg);
  box-shadow: inset 0 0 0 1px var(--glass-inner-glow);
  opacity: 0;
  transform: scale(0.92);
  transition:
    opacity var(--dur-base) var(--ease-out-soft),
    transform var(--dur-base) var(--ease-spring);
}

.lb.is-open .lb__placeholder {
  opacity: 1;
  transform: scale(1);
}

.lb__placeholder-img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 60svh;
  object-fit: cover;
}

/* 提示文字：压在占位图底部，任何尺寸都读得清 */
.lb__placeholder-hint {
  position: absolute;
  right: var(--sp-3);
  bottom: var(--sp-3);
  left: var(--sp-3);
  box-sizing: border-box;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-lg);
  background: var(--glass-bg-strong);
  backdrop-filter: blur(var(--blur-sm));
  -webkit-backdrop-filter: blur(var(--blur-sm));
  color: var(--c-ink-700);
  font-size: var(--fs-2xs);
  line-height: var(--lh-normal);
  text-align: center;
}

/* ---------- 5. 底部操作条 ---------- */

/* 布局由这里补（.glass 已给玻璃材质）。移动端一行到底，允许横向滚动兜底 */
.lb__bar {
  position: relative;
  display: flex;
  flex: 0 0 auto;
  gap: var(--sp-2);
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
  margin-top: var(--sp-2);
  padding: var(--sp-2);
  border-radius: var(--r-full);
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity var(--dur-base) var(--ease-out-soft),
    transform var(--dur-base) var(--ease-spring);
}

.lb.is-open .lb__bar {
  opacity: 1;
  transform: translateY(0);
}

.lb__counter {
  padding-inline: var(--sp-2);
  font-family: var(--ff-num);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  color: var(--c-ink-700);
  white-space: nowrap;
}

/* 圆形玻璃按钮：base.css 已给 button ≥44px 的兜底热区，这里收成正圆。
   说明：真实 DOM 把 上一张/下一张/放大/关闭 四个按钮全部放进底部 .lb__bar，
   并不浮在画面左右，所以移动端无需隐藏左右按钮（不会遮挡媒体）；
   触摸滑动由 lightbox.js 自己实现，按钮保留则照顾「不想滑动」的用户。 */
.lb__btn {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: var(--tap-min);
  height: var(--tap-min);
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  padding: 0;
  border: 1px solid var(--glass-border);
  border-radius: var(--r-full);
  background: var(--glass-bg);
  box-shadow: inset 0 1px 0 var(--glass-inner-glow);
  color: var(--c-rose-600);
  font-family: var(--ff-body);
  font-size: var(--fs-lg);
  line-height: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color var(--dur-fast) var(--ease-out-soft),
    border-color var(--dur-fast) var(--ease-out-soft),
    transform var(--dur-fast) var(--ease-spring);
}

.lb__btn:active {
  transform: scale(0.92);
}

/* JS 用 hidden/disabled 表示「只有一张，不能切换」。
   base.css 的 [hidden] 已全局兜底隐藏，这里只处理 disabled 的观感 */
.lb__btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.lb__btn--close {
  margin-left: auto;
  color: var(--c-ink-700);
}

.lb__btn--zoom[aria-pressed="true"] {
  border-color: var(--c-rose-400);
  background: color-mix(in srgb, var(--c-rose-100) 70%, transparent);
  color: var(--c-rose-600);
}

/* ---------- 6. 图注与提示 ---------- */

.lb__caption {
  display: -webkit-box;
  flex: 0 0 auto;
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
  margin: var(--sp-2) 0 0;
  padding: var(--sp-3) var(--sp-4);
  overflow: hidden;
  /* 移动端最多 3 行，超出省略 */
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  border: 1px solid var(--glass-border);
  border-radius: var(--r-lg);
  background: var(--glass-bg-strong);
  backdrop-filter: blur(var(--blur-md));
  -webkit-backdrop-filter: blur(var(--blur-md));
  box-shadow: inset 0 1px 0 var(--glass-inner-glow);
  color: var(--c-ink-700);
  font-size: var(--fs-xs);
  line-height: var(--lh-loose);
  text-align: center;
  text-wrap: pretty;
}

/* 空 caption 时 JS 会加 hidden，由 base.css 的 [hidden] 规则隐藏 */

/* 操作提示：移动端屏幕紧张，只在指针设备上显示 */
.lb__hint {
  flex: 0 0 auto;
  margin: var(--sp-1) 0 0;
  color: color-mix(in srgb, var(--c-cream-50) 62%, transparent);
  font-size: var(--fs-2xs);
  line-height: var(--lh-normal);
  text-align: center;
}

/* ---------- 7. 滚动锁 ---------- */

/* JS 已自行把 body 设为 position:fixed 并保留滚动位置，
   这里只禁止连锁滚动，避免移动端「穿透滚到底层页面」 */
html.lb-locked,
body.lb-locked {
  overscroll-behavior: none;
}

/* ---------- 8. 移动端增强（≥431px） ---------- */

@media (min-width: 431px) {
  .lb {
    padding:
      calc(var(--safe-top) + var(--sp-4))
      calc(var(--safe-right) + var(--sp-5))
      calc(var(--safe-bottom) + var(--sp-4))
      calc(var(--safe-left) + var(--sp-5));
  }

  .lb__bar {
    align-self: center;
    width: auto;
    min-width: 260px;
    padding: var(--sp-2) var(--sp-3);
  }

  .lb__caption {
    align-self: center;
    width: auto;
    max-width: 640px;
    font-size: var(--fs-sm);
    -webkit-line-clamp: 4;
  }

  .lb__placeholder-img {
    max-height: 70svh;
  }
}

/* 触屏设备隐藏键盘提示（手机上拖后腿的噪音） */
@media (hover: none) {
  .lb__hint {
    display: none;
  }
}

/* 矮屏 / 横屏：压缩垂直留白，把空间让给媒体 */
@media (max-height: 520px) {
  .lb__caption {
    -webkit-line-clamp: 2;
  }

  .lb__hint {
    display: none;
  }
}

/* ============================================================
   9. 降低动效偏好
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  /* 关掉弹性与位移动画，只留瞬时显隐，避免眩晕 */
  .lb__media,
  .lb__placeholder,
  .lb__bar,
  .lb__btn {
    transform: none;
    transition: none;
  }

  .lb.is-open .lb__media,
  .lb.is-open .lb__placeholder,
  .lb.is-open .lb__bar {
    transform: none;
  }

  /* 关闭过渡后透明度不会再被动画推进，直接给终态，避免「永远看不见」 */
  .lb__media,
  .lb__placeholder {
    opacity: 1;
  }

  .lb__btn:active {
    transform: none;
  }
}
