/* ==========================================================================
   氛围层与动效
   ==========================================================================
   性能纪律（「霓虹拉满」最大的坑就在这）：
   - 光斑用 radial-gradient，不用 filter: blur()。
     大面积 blur 在滚动时每帧重算，是这类页面卡顿的头号原因；
     radial-gradient 是静态绘制，动起来只走 transform，GPU 直接搞定。
   - 只动 transform / opacity，绝不动 box-shadow / filter / background-position。
   - 光斑只做位移，不做 scale。位移是「把已经光栅化好的图层搬个位置」，
     几乎不要钱；scale 要让合成器对满屏图层重新采样，面积还是往大里长，
     三团光叠加就是三块满屏的采样 —— 在核显上这条就是掉帧的来源。
   - 颗粒是静态的，不参与动画，否则整屏每帧重绘。
     另外它**不能挂 mix-blend-mode**：带混合模式的全屏固定层会强迫浏览器
     每一帧都把它和底下的内容重新混一遍，滚动时底下的内容一直在变，
     这个混合组就永远缓存不住。改成直接烘进噪声自身的 alpha，效果接近，代价归零。
   - 全部尊重 prefers-reduced-motion。
   ========================================================================== */

/* ---------------------------------------------------------------- 极光背景 */
.atmosphere {
  position: fixed;
  inset: 0;
  z-index: -1;              /* 沉到内容之下，不干扰交互 */
  overflow: hidden;
  pointer-events: none;
  contain: strict;          /* 隔离布局与绘制，避免影响主文档 */

  /* 切换风格配色时的交叉淡入。
     background 本身不可动画，直接换 data-style 会硬切闪一下；
     所以先让整个氛围层用 opacity 淡出（纯 GPU，不触发渐变重绘），
     在淡出期间换属性，再淡入 —— 颜色变化发生在看不见的时候。 */
  transition: opacity 260ms var(--ease-out);
}
.atmosphere.is-switching { opacity: 0.12; }

.aurora {
  position: absolute;
  border-radius: 50%;
  /* 用渐变本身做柔化，省掉 blur 滤镜 */
  will-change: transform;
  /* 整体压下去。
     极光是页面上最强的霓虹来源，而「温馨」要的恰恰不是霓虹。
     压到 0.5 之后它退成一层若有若无的光，冷暖由调色板和暖色斑块主导。 */
  opacity: 0.5;
}

/* 颜色来自 palettes.css 的 --aurora-* 变量（RGB 三元组），
   所以换 data-style 就等于换掉这三团光的颜色。 */
.aurora--1 {
  width: 62vw;
  height: 62vw;
  top: -22vw;
  left: -14vw;
  background: radial-gradient(circle,
    rgb(var(--aurora-1) / 0.34) 0%,
    rgb(var(--aurora-1) / 0.16) 38%,
    transparent 68%);
  animation: drift-1 34s ease-in-out infinite alternate;
}

.aurora--2 {
  width: 54vw;
  height: 54vw;
  top: -8vw;
  right: -16vw;
  background: radial-gradient(circle,
    rgb(var(--aurora-2) / 0.26) 0%,
    rgb(var(--aurora-2) / 0.12) 40%,
    transparent 70%);
  animation: drift-2 42s ease-in-out infinite alternate;
}

.aurora--3 {
  width: 70vw;
  height: 58vw;
  bottom: -30vw;
  left: 18vw;
  background: radial-gradient(circle,
    rgb(var(--aurora-3) / 0.24) 0%,
    rgb(var(--aurora-3) / 0.10) 42%,
    transparent 72%);
  animation: drift-3 50s ease-in-out infinite alternate;
}

/* 只走位移，不带 scale（原因见文件头的性能纪律） */
@keyframes drift-1 {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(6vw, 4vw, 0); }
}
@keyframes drift-2 {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-5vw, 6vw, 0); }
}
@keyframes drift-3 {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-7vw, -4vw, 0); }
}

/* 亮色主题下光斑要淡很多，否则整页发灰 */
html[data-theme="light"] .aurora--1 { opacity: 0.55; }
html[data-theme="light"] .aurora--2 { opacity: 0.5; }
html[data-theme="light"] .aurora--3 { opacity: 0.45; }

/* 窄屏上三团光几乎铺满整屏，持续位移＝每帧都在合成长满屏的三层半透明，
   而这类设备的 GPU 预算恰恰最少。保留配色、停掉位移：观感几乎不变，帧率稳了。 */
@media (max-width: 700px) {
  .aurora { animation: none; }
}

/* ---------------------------------------------------------------- 颗粒 */
/* 噪点让纯色背景有「材质」，是氛围感的关键一层。
   用 SVG feTurbulence 生成，零额外请求。

   关键：不用 mix-blend-mode，而是把噪声直接做成「白色/黑色 + 噪声 alpha」。
   混合模式的全屏固定层会强迫浏览器每帧把它和底下的内容重混一遍，
   滚动时底下一直在变，混合组就永远缓存不住 —— 这正是滚动发涩的常见来源。
   直接把 alpha 烘进噪声图，视觉效果几乎一样，但这一层退化成普通静态贴图。
   亮色主题换一张「黑噪点」，不用混合模式也能两种主题都成立。 */
.grain {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  contain: strict;
  opacity: 0.16;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0.6 0.6 0.6 0 -0.72'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 200px 200px;
}
html[data-theme="light"] .grain {
  opacity: 0.1;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.6 0.6 0.6 0 -0.72'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------------------------------------------------------------- 照片底 */
/* 铺满整页的时装摄影底图。素材来自参考海报，文字已由 scripts/make-backdrop.js 抹掉。
   两张不同排布的图缓慢交叉淡入 —— 这是「鲜活」的来源，而且只动 opacity：
   不重绘、不重采样，比动 transform 的缩放还便宜。
   沉在 z-index:-2（编辑排版层之下），卡片不透明，所以它主要在留白和页脚一带露出来。 */
.backdrop {
  position: fixed;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  pointer-events: none;
  contain: strict;
  background: var(--bg-0);
}

.backdrop__layer {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  will-change: opacity;
}

.backdrop__layer--a {
  background-image: url("/img/editorial/backdrop-a.webp");
  /* 这是背景「存在感」的总开关 —— 只有一个数字，想调就改这里。
     注意这调的是**不透明度**，不是模糊。 */
  opacity: 0.42;
  /* 极慢的位移 —— 只走 transform，和极光那层同样的纪律 */
  animation: backdrop-drift 96s ease-in-out infinite alternate;
}
.backdrop__layer--b {
  background-image: url("/img/editorial/backdrop-b.webp");
  opacity: 0;
  animation: backdrop-swap 76s ease-in-out infinite;
}
/* 第三张与 b 反相：b 涨到顶时 c 在谷底，于是整页始终有一张在淡入、
   一张在淡出，两两交叠 —— 背景在缓慢「换气」，而没有任何一帧是全暗的。
   代价仍然只有 opacity。 */
.backdrop__layer--c {
  background-image: url("/img/editorial/backdrop-c.webp");
  opacity: 0;
  animation: backdrop-swap 76s ease-in-out infinite;
  animation-delay: -38s;
}

/* 内容可读性蒙版。照片再柔，正文直接压上去也会糊；这一层把背景往**页面色**
   拉回来，所以主题一变它跟着变（--bg-0 是当前主题的底色，亮色主题下自动变成
   「提亮」而不是「压暗」—— 这里不需要写两套）。
   上厚下薄：顶部是导航和首屏标题所在，需要最实的底。 */
.backdrop__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--bg-0) 72%, transparent) 0%,
    color-mix(in srgb, var(--bg-0) 50%, transparent) 26%,
    color-mix(in srgb, var(--bg-0) 38%, transparent) 62%,
    color-mix(in srgb, var(--bg-0) 56%, transparent) 100%
  );
}

/* 色斑 —— 整页色调的来源。
   照片素材本身低饱和，单靠照片画面会寡淡；加几团大而柔的色，整页才有底色。

   **颜色取自 --aurora-\*，也就是当前风格配色。** 这一层原来写死了六团暖色，
   结果是「选风格换配色」只生效了一半：极光和 chip 变了色，占画面最大面积的
   这一层纹丝不动 —— 切到「通勤（蓝）」整页还是琥珀色。改成跟着风格走之后，
   换风格**整页**才会真的换色。

   为什么放在 CSS 而不是烤进图片：照片层的不透明度只有 0.4 上下，
   烤进去的颜色会跟着一起被压掉（试过，页面上完全看不见）。
   这一层不透明度是 1，颜色才是实打实的。 */
.backdrop__tint {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(48% 48% at 12% 18%, rgb(var(--aurora-1) / 0.34), transparent 72%),
    radial-gradient(44% 44% at 80% 12%, rgb(var(--aurora-2) / 0.32), transparent 72%),
    radial-gradient(50% 50% at 26% 82%, rgb(var(--aurora-3) / 0.30), transparent 72%),
    radial-gradient(46% 46% at 88% 72%, rgb(var(--aurora-1) / 0.26), transparent 72%),
    radial-gradient(40% 40% at 52% 46%, rgb(var(--aurora-2) / 0.24), transparent 72%),
    radial-gradient(38% 38% at 40% 6%,  rgb(var(--aurora-3) / 0.26), transparent 72%);
}

/* b 在 a 之上淡入淡出，两者交替，背景就一直在缓慢变化 */
@keyframes backdrop-swap {
  0%   { opacity: 0; }
  50%  { opacity: 0.50; }
  100% { opacity: 0; }
}
@keyframes backdrop-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-1.6%, -1.1%, 0); }
}

/* 亮色主题：照片要更淡，否则整页发花、文字读不清 */
html[data-theme="light"] .backdrop__layer--a { opacity: 0.40; }
html[data-theme="light"] .backdrop__layer--b,
html[data-theme="light"] .backdrop__layer--c { animation-name: backdrop-swap-light; }
@keyframes backdrop-swap-light {
  0%   { opacity: 0; }
  50%  { opacity: 0.40; }
  100% { opacity: 0; }
}

/* ---------------------------------------------------------------- 飘落的花瓣 */
/* 「鲜活」的来源之一：几片慢慢飘下来的花瓣。
   三条纪律：
   1. **只动 transform / opacity** —— 和极光、照片底同一套，合成器就能搞定。
   2. **沉在内容之下**（z-index:-1）。卡片不透明，所以它们主要在页边留白和
      卡片缝隙里飘过，不会跑到文字上面去。
   3. 数量少（8 片）、尺寸小（10–20px），代价可以忽略。
   颜色取自 --aurora-3，跟着风格配色走。 */
.petals {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  contain: strict;
}

.petal {
  position: absolute;
  top: 0;
  width: 14px;
  height: 14px;
  /* 花瓣形：对角圆角 */
  border-radius: 100% 0 100% 0;
  background: rgb(var(--aurora-3) / 0.40);
  opacity: 0;
  will-change: transform, opacity;
  animation: petal-fall linear infinite;
}

/* 每片的位置、大小、节奏各不相同 —— 全都一样的话会像雨刷，不像花瓣。
   12 片减到 6 片：花瓣只是给留白加一点偶然性，铺满一屏反而把背景的层次搅碎，
   和照片底抢戏。少而稀才有「偶尔飘过一片」的意思。 */
.petal:nth-child(1) { left: 8%;  width: 16px; height: 16px; animation-duration: 38s; animation-delay: -3s;  --drift: 7vw;  }
.petal:nth-child(2) { left: 26%; width: 11px; height: 11px; animation-duration: 50s; animation-delay: -18s; --drift: -5vw; }
.petal:nth-child(3) { left: 44%; width: 18px; height: 18px; animation-duration: 43s; animation-delay: -27s; --drift: 9vw;  }
.petal:nth-child(4) { left: 62%; width: 12px; height: 12px; animation-duration: 56s; animation-delay: -9s;  --drift: -7vw; }
.petal:nth-child(5) { left: 79%; width: 15px; height: 15px; animation-duration: 45s; animation-delay: -33s; --drift: 6vw;  }
.petal:nth-child(6) { left: 93%; width: 10px; height: 10px; animation-duration: 52s; animation-delay: -12s; --drift: -8vw; }

@keyframes petal-fall {
  0%   { transform: translate3d(0, -14vh, 0) rotate(0deg); opacity: 0; }
  8%   { opacity: 0.55; }
  88%  { opacity: 0.55; }
  100% { transform: translate3d(var(--drift, 6vw), 114vh, 0) rotate(560deg); opacity: 0; }
}

/* 亮色主题下花瓣要更实一点，否则白底上看不见 */
html[data-theme="light"] .petal { background: rgb(var(--aurora-3) / 0.34); }

@media (prefers-reduced-motion: reduce) {
  .petal { animation: none; opacity: 0; }
}

/* ---------------------------------------------------------------- 编辑排版层 */
/* 时装杂志的版面语言：发丝分隔线 + 大字号衬线标题（词刻意断行）+ 页边拉宽字距的拉丁小标签。
   三条纪律：
   1. **全静态**。背景已经有极光在动，再塞会动的东西，合成代价成倍上去。
   2. **只用系统字体**（Georgia / 宋体）。引外链字体等于给首屏加一次网络往返，
      和这个项目「零额外请求」的取向相反。
   3. 沉在 z-index:-1，而卡片不透明 —— 所以它只在页边留白和卡片缝隙里露出来。
      换句话说：它是给「留白」做设计的，不是给内容做背景的。 */
.editorial {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  contain: strict;

  /* 用 --text-0 而不是某个固定色：暗色主题下是浅墨、亮色下是深墨，
     两边都成立，不用为每个主题各写一套。 */
  color: var(--text-0);
  opacity: 0.13;
  font-family: var(--font-editorial);
}
html[data-theme="light"] .editorial { opacity: 0.16; }

/* 发丝分隔线。
   **只画页边那一段**，不做通栏：通栏会被卡片盖住，只在卡片缝隙里露出来，
   看起来像渲染错误而不是版面设计。参考图里这些线的作用是「切开版面」，
   放在页边当刻度用更贴切。 */
.editorial__rule {
  position: absolute;
  background: currentColor;
}
.editorial__rule--v  { left: 6%; top: 0; bottom: 0; width: 1px; opacity: 0.5; }
.editorial__rule--h1 { left: 0; width: 3.6%; top: 17%; height: 1px; opacity: 0.45; }
.editorial__rule--h2 { right: 0; width: 3.6%; bottom: 12%; height: 1px; opacity: 0.45; }

/* 大字号衬线标题 —— **竖排**。
   一开始是照参考图横排的，实测放不下：1440 视口下内容列两侧各只剩 120px 留白，
   而横排的标题动辄三四百像素宽，会被卡片压掉大半，只剩几个残字，像事故。
   竖排只占一条窄带，页边留白一定塞得下，而且杂志书脊本来就是这么排的。
   词仍按参考图的做法拆行（SILHOU / ETTE）。 */
.editorial__display {
  position: absolute;
  /* 贴着右边，留出「两列竖排字」的宽度。算过：1440 视口下两列约 84px，
     而内容列右侧留白是 120px，1.8% 刚好放得下。 */
  right: 1.8%;
  top: 12%;
  writing-mode: vertical-rl;
  font-size: clamp(26px, 2.9vw, 48px);
  line-height: 0.95;
  letter-spacing: 0.01em;
  text-transform: uppercase;
}

/* 页边小标签：小号、字距拉开，是这类版面里最出效果的一笔。
   只有竖排的能常驻 —— 横排的在小视口下必然超宽（见上面 display 的说明），
   所以横排的两条交给 ≥1520px 的媒体查询，那时两侧留白才够。 */
.editorial__label {
  position: absolute;
  font-family: var(--font-sans);
  font-size: 10px;
  font-weight: var(--fw-medium);
  letter-spacing: 0.34em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* 竖排：writing-mode 比 rotate 干净 —— 行内方向、断行、标点都交给浏览器 */
.editorial__label--c {
  top: 30%;
  left: 4.4%;
  writing-mode: vertical-rl;
  letter-spacing: 0.4em;
}
.editorial__label--d {
  bottom: 16%;
  right: 4.4%;
  writing-mode: vertical-rl;
  letter-spacing: 0.4em;
}

/* 横排标签：留白够宽才出场 */
.editorial__label--a,
.editorial__label--b { display: none; }

@media (min-width: 1520px) {
  .editorial__label--a { display: block; top: 9%;  right: 4.4%; }
  .editorial__label--b { display: block; top: 21%; right: 4.4%; }
}

/* 这套东西全部住在「页边留白」里，所以留白不够就整个收掉。
   容器是 1200px，视口低于 1400px 时两侧各不到 100px —— 放不下竖排标题，
   硬放只会被卡片切成一堆残字。
   换句话说：这个效果本来就是给宽屏看的，窄屏上让它消失比让它残缺好。 */
@media (max-width: 1400px) {
  .editorial { display: none; }
}

/* ---------------------------------------------------------------- 滚动入场 */
.reveal {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
}
.reveal.is-in {
  opacity: 1;
  transform: none;
}

/* ---------------------------------------------------------------- 卡片高光扫过 */
/* 卡片的「元素感」补充：hover 时一道斜向高光扫过封面。
   只动 transform，且用伪元素，不影响布局。 */
.post-card__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    105deg,
    transparent 38%,
    rgba(255, 255, 255, 0.16) 48%,
    rgba(255, 255, 255, 0.05) 54%,
    transparent 64%
  );
  transform: translate3d(-120%, 0, 0);
  opacity: 0;
  pointer-events: none;
}
.post-card:hover .post-card__media::after {
  opacity: 1;
  animation: shine-sweep 900ms var(--ease-out);
}
@keyframes shine-sweep {
  from { transform: translate3d(-120%, 0, 0); }
  to   { transform: translate3d(120%, 0, 0); }
}

/* ---------------------------------------------------------------- 霓虹描边 */
/* hover 时沿卡片外沿浮现一圈渐变光。用 mask 做出「只有边框」的效果，
   比大半径 box-shadow 便宜得多。 */
.glow-ring {
  position: relative;
}
.glow-ring::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: var(--grad-border);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
  pointer-events: none;
}
.glow-ring:hover::before { opacity: 1; }

/* ---------------------------------------------------------------- 顶部霓虹线 */
/* 导航底部一道渐变细线，暗示品牌的霓虹身份，且是静态的，不花性能 */
.nav::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(232, 150, 60, 0.55) 22%,
    rgba(207, 106, 62, 0.65) 50%,
    rgba(226, 88, 107, 0.55) 78%,
    transparent 100%
  );
  pointer-events: none;
}

/* ---------------------------------------------------------------- 点赞粒子 */
/* 点赞时中心扩散一圈光环。只动 transform + opacity。
   用独立元素而不是伪元素，方便按需创建销毁。 */
.like-burst {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 26px;
  height: 26px;
  margin: -13px 0 0 -13px;
  border-radius: 50%;
  border: 2px solid var(--neon-pink, #e2586b);
  pointer-events: none;
  animation: burst 520ms var(--ease-out) forwards;
}
@keyframes burst {
  from { transform: scale(0.3); opacity: 0.9; }
  to   { transform: scale(2.1); opacity: 0; }
}

/* 让点赞按钮能承载绝对定位的粒子 */
.metric { position: relative; }

/* ---------------------------------------------------------------- 品牌字 */
.nav__wordmark {
  display: flex;
  flex-direction: column;
  line-height: 1;
  gap: 2px;
}
.nav__name { font-size: var(--fs-lg); letter-spacing: -0.03em; }
.nav__latin {
  font-size: 8px;
  letter-spacing: 0.22em;
  color: var(--text-2);
  font-weight: var(--fw-medium);
}

/* ---------------------------------------------------------------- 数字滚动感 */
/* 统计数字用等宽字形，数值变化时不会左右跳动 */
.tabular { font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------- 减少动效 */
@media (prefers-reduced-motion: reduce) {
  .aurora { animation: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .post-card:hover .post-card__media::after { animation: none; opacity: 0; }
  .like-burst { display: none; }
  /* 照片底停掉交叉淡入，只留第一张的静态底 */
  .backdrop__layer--a { animation: none; }
  .backdrop__layer--b { animation: none; opacity: 0; }
  .backdrop__layer--c { animation: none; opacity: 0; }
}
