/* 渐进模糊（2026-10-11），挂载逻辑在 js/blur.js。
   做法移植自 React Bits 的 GradualBlur（本站是原生 JS，没有装那个 React 组件，只照它的分层方式写成纯 CSS）：
   五层叠在一起，每层 backdrop-filter 的模糊半径递增，各自用一段首尾交叠的渐变蒙版只露出一条带——
   第 n 层从 20(n-1)% 淡入、20n%–20(n+1)% 全显、到 20(n+2)% 淡出——叠起来就是从清晰到模糊的连续过渡，没有一刀切的边。
   --gb 是整体强度倍率（各层半径 1 / 2 / 4 / 8 / 14px × --gb），也是显隐的过渡量：
   不能靠父层 opacity 淡入——opacity 小于 1 的父层会把子层的 backdrop 截断，过渡途中什么都糊不到。 */

@property --gb {
  syntax: '<number>';
  inherits: true;
  initial-value: 1;
}

.gblur {
  position: absolute;
  pointer-events: none;
  --gb: 1;
}
.gblur > i {
  position: absolute;
  inset: 0;
  -webkit-backdrop-filter: blur(calc(var(--b) * var(--gb)));
  backdrop-filter: blur(calc(var(--b) * var(--gb)));
  -webkit-mask-image: linear-gradient(var(--gb-to), transparent var(--p1), #000 var(--p2), #000 var(--p3), transparent var(--p4));
  mask-image: linear-gradient(var(--gb-to), transparent var(--p1), #000 var(--p2), #000 var(--p3), transparent var(--p4));
}
.gblur > i:nth-child(1) { --b: 1px;  --p1: 0%;  --p2: 20%;  --p3: 40%;  --p4: 60%; }
.gblur > i:nth-child(2) { --b: 2px;  --p1: 20%; --p2: 40%;  --p3: 60%;  --p4: 80%; }
.gblur > i:nth-child(3) { --b: 4px;  --p1: 40%; --p2: 60%;  --p3: 80%;  --p4: 100%; }
.gblur > i:nth-child(4) { --b: 8px;  --p1: 60%; --p2: 80%;  --p3: 100%; --p4: 120%; }
.gblur > i:nth-child(5) { --b: 14px; --p1: 80%; --p2: 100%; --p3: 120%; --p4: 140%; }

/* 渐变指向哪边，哪边最糊 */
.gblur--top    { --gb-to: to top; }
.gblur--bottom { --gb-to: to bottom; }
.gblur--left   { --gb-to: to left; }
.gblur--right  { --gb-to: to right; }

/* 出现 / 收起：模糊半径从 0 长出来 */
.gblur--bar,
.gblur--edge {
  --gb: 0;
  visibility: hidden;
  transition: --gb 0.5s ease, visibility 0s linear 0.5s;
}
.gblur--bar.is-shown,
.gblur--edge.is-shown {
  visibility: visible;
  transition: --gb 0.5s ease, visibility 0s;
}

/* ── 1. 顶部 / 底部：垫在四角固定文字下面 ──
   左上标签、顶部导航、右上时间、左下邮箱、右下状态都是直接压在正文上的小字，滚动时和正文叠在一起两边都看不清。
   放在 .page 里（它自成层叠上下文）：压住正文，但在 3D 入口（同在 .page 里，z 100）之下；
   红线、竖栏、HUD 都在 .page 之外，保持清晰。首屏不出（和顶部导航同一个时机）。
   顶条高 80px：导航跳转后区块标签落在 y 81，正好不沾。 */
.gblur--bar {
  position: fixed;
  left: 0;
  right: 0;
  z-index: 90;
}
.gblur--bar.gblur--top { top: 0; height: 80px; }
.gblur--bar.gblur--bottom { bottom: 0; height: 44px; }   /* 只垫住最底下那一行字（离底 22–37px），不往上吃正文 */
.gblur--bar.gblur--top.is-shown { --gb: 1.6; }
.gblur--bar.gblur--bottom.is-shown { --gb: 1; }
/* 再压一点暗：光糊掉还不够，亮色大字糊开后仍是一团亮，小字压在上面照样吃力 */
.gblur--bar::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(var(--gb-to), transparent, rgba(8, 8, 8, 0.72) 45%, rgba(8, 8, 8, 0.9));
  opacity: 0;
  transition: opacity 0.5s ease;
}
.gblur--bar.is-shown::after { opacity: 1; }
.gblur--bar.gblur--bottom.is-shown::after { opacity: 0.8; }

/* ── 2. 作品横滑条两端 ──
   卡片原来在内容边线上一刀切断。两端各盖一条窄的：大半伸在内容边线外面，把切口化开；
   压进卡片的只有 28px（卡片标题左边正好留着 23px 的内边距），不糊到字。
   还能往哪边滑，哪边才出（js/blur.js 按滚动位置切 is-shown）。 */
.projects > .gblur--edge {
  top: 0;
  bottom: 20px;            /* 让出滚动条那 20px */
  width: 72px;
  z-index: 25;
}
.projects > .gblur--left { left: -44px; }
.projects > .gblur--right { right: -44px; }
.projects > .gblur--edge.is-shown { --gb: 1; }
.projects:not([data-mode="slider"]) > .gblur--edge { display: none; }

/* ── 3. 品牌 / 工具两行滚动带的两端 ──
   原来只有透明度淡出（.logos__viewport 的 mask）；叠一层渐进模糊，标志是「由虚到实」地进出，而不只是变淡。
   舞台是 js 包在 viewport 外面的一层：模糊层不能放进带 mask 的元素里。 */
.logos__stage { position: relative; }
.logos__stage > .gblur {
  top: -18px;              /* 上下多伸一点：糊开的边不能被舞台的上下沿切成一个方块 */
  bottom: -18px;
  width: 16%;
  --gb: 0.7;
}
.logos__stage > .gblur--left { left: 0; }
.logos__stage > .gblur--right { right: 0; }

@media (max-width: 720px) {
  .gblur--bar.gblur--top { height: 52px; }   /* 窄屏区块上边距 56px，标签落在 y 57 */
  .projects > .gblur--edge { width: 36px; }
  .projects > .gblur--left { left: -16px; }
  .projects > .gblur--right { right: -16px; }
  .logos__stage > .gblur { width: 14%; }
}
/* 「减少动效」下滚动带停住、改成手动横滑，两端不该再糊着 */
@media (prefers-reduced-motion: reduce) {
  .logos__stage > .gblur { display: none; }
}
/* 窄屏左下的邮箱已经隐藏，底部没有需要垫的字 */
@media (max-width: 420px) {
  .gblur--bar.gblur--bottom { display: none; }
}
