/* ==========================================================================
   缘梦 YuanMoon · 组件与构成
   构成原则：非对称、重叠、破格。
   首屏那轮月亮刻意冲出右侧画布边缘 —— 每屏都有一个元素逃出栅格。
   ========================================================================== */

/* ======================================================================
   1. 氛围层：星场 + 颗粒
   深空不能是平涂的近黑色，否则整站会显得廉价而空洞。
   ====================================================================== */
.starfield {
  position: fixed;
  inset: 0;
  z-index: var(--z-stars);
  pointer-events: none;
  overflow: hidden;
}

.starfield__svg {
  width: 100%;
  height: 100%;
}

/* 月晕：两团极淡的径向光，一团暖金（月亮的方向），一团冷蓝（地球反照） */
.starfield__glow {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(58rem 42rem at 82% 22%, color-mix(in srgb, var(--halo-300) 9%, transparent), transparent 62%),
    radial-gradient(48rem 40rem at 8% 78%, rgba(94, 116, 190, 0.11), transparent 60%);
}

.star {
  fill: var(--moon-200);
  animation: twinkle var(--twinkle-dur, 5s) ease-in-out infinite;
  animation-delay: var(--twinkle-delay, 0s);
}

@keyframes twinkle {
  0%, 100% { opacity: var(--star-min, 0.18); }
  50%      { opacity: var(--star-max, 0.7); }
}

/* 颗粒：3% 的噪点，让深空有"胶片"的实体感，压住渐变的塑料味 */
.grain {
  position: fixed;
  inset: 0;
  /* 压在内容之上，连顶部导航一起覆盖，这样颗粒才是"整张照片"的颗粒。
     3.5% 的强度不会影响任何文字的清晰度。 */
  z-index: 100;
  pointer-events: none;
  opacity: 0.035;
  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='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ======================================================================
   2. 顶部导航
   ====================================================================== */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  /* 用显式的 width:100% + max-width 而不是 left/right 同时为 0 ——
     后者在窄视口下会算出比视口更宽的盒子，把导航整个顶出屏幕。
     品牌和导航靠 margin-right:auto 分流，比 space-between 更不容易被压缩逻辑干扰。 */
  width: 100%;
  max-width: 100vw;
  box-sizing: border-box;
  z-index: var(--z-header);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--page-pad);
  /* 滚动后才显形，首屏不抢月亮的戏 */
  background: linear-gradient(180deg, rgba(4, 6, 13, 0.92), rgba(4, 6, 13, 0));
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: transform var(--dur-base) var(--ease-out),
              opacity var(--dur-base) var(--ease-out);
}

/* 页面未滚动时，导航是"轻"的；一旦滚动就实体化 */
.site-header[data-scrolled="false"] {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;
  padding: var(--space-1) 0;
  /* 把导航推到最右 */
  margin-right: auto;
}

.brand__mark {
  width: 30px;
  height: 30px;
  flex: none;
  transition: transform var(--dur-slow) var(--ease-out);
}
.brand:hover .brand__mark {
  transform: rotate(-18deg);
}

.brand__text {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}

.brand__cn {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: 0.12em;
}

.brand__en {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.site-nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--fs-sm);
  color: var(--color-text-soft);
  letter-spacing: 0.08em;
  transition: color var(--dur-fast) ease-out;
}

/* 悬停时下划线从左向右扫过，而不是整条变亮 */
.site-nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 12px;
  width: 100%;
  height: 1px;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-base) var(--ease-out);
}
.site-nav__link:hover {
  color: var(--color-text);
}
.site-nav__link:hover::after {
  transform: scaleX(1);
}

/* 窄屏导航：这是整站最容易出问题的地方。
   品牌名 + 三个中文链接挤在一行里，一旦 flex 压缩生效，中文会先断行、
   再被挤出视口 —— 手机上就只剩一个入口了。所以这里明确禁止压缩，
   并把间距和字号一起收一收，给 360px 宽的老设备也留足余量。 */
@media (max-width: 640px) {
  .site-header {
    gap: var(--space-3);
    padding: var(--space-3) var(--page-pad);
  }
  .brand,
  .site-nav {
    flex: none;
  }
  .brand {
    gap: var(--space-2);
  }
  .brand__mark {
    width: 26px;
    height: 26px;
  }
  .brand__cn {
    font-size: var(--fs-base);
    letter-spacing: 0.08em;
  }
  .brand__en {
    display: none;
  }
  .site-nav {
    gap: var(--space-3);
  }
  .site-nav__link {
    font-size: var(--fs-xs);
    letter-spacing: 0.02em;
    white-space: nowrap;
  }
  .site-nav__link::after {
    bottom: 14px;
  }
}

/* ======================================================================
   3. 首屏
   月亮右侧出血，文字从左侧压在月亮边缘上。
   ====================================================================== */
.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  align-content: center;
  padding: calc(var(--space-8) + 40px) var(--page-pad) var(--space-7);
  isolation: isolate;
  /* 月亮要出血，但出血不能变成横向滚动条。
     在 hero 这一层裁掉，比指望 body 的 overflow-x 兜底可靠得多。 */
  overflow: hidden;
}

/* ---- 月亮 ------------------------------------------------------------- */
.hero__moon {
  position: absolute;
  top: 50%;
  /* 刻意冲出右侧画布：每屏都要有一个元素逃出栅格。
     月亮直径约占元素宽度的 70%（viewBox 400 里圆的半径 140），
     所以元素还要再往右推一截，裁掉的才是月亮本体而不是空白。 */
  right: clamp(-240px, -16vw, -100px);
  z-index: -1;
  width: clamp(320px, 54vw, 780px);
  aspect-ratio: 1 / 1;
  /* 定位与视差统一交给 translate 属性，把 transform 和 scale 让给入场动画，
     三者在浏览器里是独立的属性，不会互相覆盖。 */
  translate: 0 calc(-50% + var(--moon-parallax, 0px));
  will-change: translate;
}

.hero__moon-svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* 月晕：月亮外圈那层柔和的光，随相位增亮。
   初始值不能太低 —— 新月时整轮月亮只有暗面，全靠这圈光和金边把轮廓托出来。 */
.moon__halo {
  fill: none;
  opacity: var(--halo-opacity, 0.2);
  transition: opacity var(--dur-base) linear;
}

/* 整个月盘：亮面随相位扩张，暗面始终可辨（真实月亮就是这样） */
.moon__lit {
  fill: url(#moonLit);
}
.moon__earthshine {
  /* 填充由 HTML 里的 moonDark 径向渐变提供 —— 地球反照的微光 */
  fill: url(#moonDark);
}

.hero__moon-caption {
  position: absolute;
  left: 50%;
  bottom: -6%;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--color-faint);
  white-space: nowrap;
}
.hero__moon-caption b {
  color: var(--color-accent);
  font-weight: 400;
}

/* ---- 首屏文字 --------------------------------------------------------- */
.hero__text {
  position: relative;
  z-index: 1;
  max-width: 34rem;
  display: grid;
  gap: var(--space-4);
}

.hero__title {
  display: grid;
  gap: 0;
  line-height: 0.9;
}

.hero__title-cn {
  font-family: var(--font-display);
  font-size: var(--fs-display);
  font-weight: 600;
  letter-spacing: 0.06em;
  /* 中文标题给一点宽度变体感：字距拉开，像星图上的标注 */
}

.hero__title-en {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.5rem, 4.4vw, 3rem);
  letter-spacing: 0.02em;
  color: var(--color-accent);
  margin-top: calc(var(--space-1) * -1);
}

.hero__lede {
  font-size: var(--fs-md);
  line-height: 1.85;
  color: var(--color-text-soft);
  max-width: 26em;
}

.hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-faint);
}
.hero__meta span {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.hero__meta span::before {
  content: "";
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--color-accent-deep);
}

/* ---- 按钮 ------------------------------------------------------------- */
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-2);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 48px;
  padding: 0 var(--space-5);
  border-radius: var(--radius-full);
  border: 1px solid transparent;
  font-size: var(--fs-sm);
  letter-spacing: 0.1em;
  cursor: pointer;
  transition: background-color var(--dur-fast) ease-out,
              border-color var(--dur-fast) ease-out,
              color var(--dur-fast) ease-out,
              transform var(--dur-fast) ease-out;
}
.btn:active {
  transform: translateY(1px);
}

.btn--primary {
  background: var(--color-accent);
  color: var(--ink-950);
  font-weight: 500;
}
.btn--primary:hover {
  background: var(--color-accent-soft);
}

.btn--ghost {
  border-color: var(--color-border-strong);
  color: var(--color-text-soft);
}
.btn--ghost:hover {
  border-color: var(--color-border-accent);
  color: var(--color-text);
  background: color-mix(in srgb, var(--halo-300) 6%, transparent);
}

/* 禁用态：整个站点的按钮都可能有这一态 */
.btn[aria-disabled="true"],
.btn:disabled {
  opacity: 0.42;
  cursor: not-allowed;
  pointer-events: none;
}

/* ---- 滚动提示 --------------------------------------------------------- */
.hero__cue {
  position: absolute;
  left: var(--page-pad);
  bottom: var(--space-5);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--color-faint);
}
.hero__cue-line {
  position: relative;
  width: 56px;
  height: 1px;
  background: var(--color-border-strong);
  overflow: hidden;
}
.hero__cue-line::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--color-accent);
  transform-origin: left;
  animation: sweep 2.6s var(--ease-inout) infinite;
}
@keyframes sweep {
  0%   { transform: scaleX(0); }
  45%  { transform: scaleX(1); }
  100% { transform: scaleX(1); opacity: 0; }
}

@media (max-width: 900px) {
  .hero {
    align-content: start;
    min-height: auto;
    padding: calc(var(--space-7) + 48px) var(--page-pad) var(--space-7);
    gap: var(--space-4);
  }
  /* 小屏上让月亮回到文档流、单独占一块 ——
     375px 宽的屏幕上，月亮一旦和文字重叠就一定读不清 */
  .hero__moon {
    position: relative;
    top: auto;
    right: auto;
    translate: none;
    justify-self: center;
    width: min(58vw, 250px);
    z-index: 0;
  }
  .hero__text { max-width: none; }
  .hero__lede { font-size: var(--fs-base); }
  .hero__moon-caption { display: none; }
  .hero__cue { display: none; }
}

/* ======================================================================
   4. 区块通用骨架
   ====================================================================== */
.section {
  position: relative;
  z-index: var(--z-content);
  padding: var(--space-8) var(--page-pad);
  max-width: var(--page-max);
  margin: 0 auto;
}

.section__head {
  display: grid;
  gap: var(--space-3);
  margin-bottom: var(--space-7);
  max-width: 42rem;
}

/* 发丝分割线：从标题右侧延伸出去，制造"未完成"的横向动势 */
.section__rule {
  height: 1px;
  background: linear-gradient(90deg, var(--color-border-strong), transparent);
  margin-bottom: var(--space-6);
}

/* ======================================================================
   5. 缘起：名字释义
   四个字，用非对称网格排，不复用同一张卡片模板。
   ====================================================================== */
.gloss {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--space-5) var(--space-4);
  list-style: none;
  padding: 0;
  margin: 0;
}

.gloss__item {
  display: grid;
  gap: var(--space-3);
  align-content: start;
}

/* 刻意错落：四个字不在同一水平线上。
   第 3 个的负 margin 只给 -40px —— 给太多的话，以后文案一改长就会压到上面一行。 */
.gloss__item:nth-child(1) { grid-column: 1 / span 5; }
.gloss__item:nth-child(2) { grid-column: 7 / span 5; margin-top: var(--space-7); }
.gloss__item:nth-child(3) { grid-column: 2 / span 5; margin-top: calc(var(--space-5) * -1); }
.gloss__item:nth-child(4) { grid-column: 8 / span 5; margin-top: var(--space-5); }

.gloss__glyph {
  font-family: var(--font-display);
  font-size: clamp(4rem, 9vw, 7rem);
  font-weight: 400;
  line-height: 0.85;
  color: transparent;
  -webkit-text-stroke: 1px var(--color-border-strong);
  transition: -webkit-text-stroke-color var(--dur-base) ease-out,
              color var(--dur-base) ease-out;
}
.gloss__item:hover .gloss__glyph {
  -webkit-text-stroke-color: var(--color-accent);
  color: color-mix(in srgb, var(--halo-300) 6%, transparent);
}

.gloss__item h3 {
  font-size: var(--fs-md);
  letter-spacing: 0.14em;
  color: var(--color-text);
}

.gloss__item p {
  font-size: var(--fs-sm);
  line-height: 1.9;
  color: var(--color-muted);
}

@media (max-width: 900px) {
  .gloss { grid-template-columns: 1fr; gap: var(--space-6); }
  .gloss__item,
  .gloss__item:nth-child(n) {
    grid-column: auto;
    margin-top: 0;
  }
  .gloss__glyph { font-size: 3.5rem; }
}

/* ======================================================================
   6. 作品：三张入口卡片
   卡片用月相做图标 —— 月相即进度，占位态是"新月"，上线后"转满"。
   ====================================================================== */
.works {
  display: grid;
  /* 四张卡：2×2 比 3+1 稳。3 列会让第四张单独落在第二行，很难看 */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
  align-items: start;
}

.work {
  position: relative;
  display: grid;
  gap: var(--space-3);
  padding: var(--space-5);
  background: linear-gradient(180deg, var(--color-surface), var(--ink-850));
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: border-color var(--dur-base) ease-out,
              transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) ease-out;
}

/* 卡片倒错：2 列网格里，左列和右列各自往下错一点，
   幅度刻意压小（16 / 24 / 40px）—— 大偏移会让三张卡读起来像缺了一张。
.work:nth-child(2) { margin-top: var(--space-5); }
.work:nth-child(3) { margin-top: var(--space-3); }
.work:nth-child(4) { margin-top: var(--space-4); }

.work:hover {
  border-color: var(--color-border-accent);
  transform: translateY(-6px);
  box-shadow: var(--shadow-2), var(--glow-halo);
}

/* 悬停时从右上角洇开一层极淡的金色 */
.work::before {
  content: "";
  position: absolute;
  top: -40%;
  right: -30%;
  width: 70%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--halo-300) 16%, transparent), transparent 68%);
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
  pointer-events: none;
}
.work:hover::before {
  opacity: 1;
}

.work__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.work__phase {
  width: 40px;
  height: 40px;
  flex: none;
}

.work__tag {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-faint);
}

.work__title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.3;
}

.work__desc {
  font-size: var(--fs-sm);
  line-height: 1.85;
  color: var(--color-muted);
}

.work__status {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding: 5px var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.14em;
  color: var(--color-muted);
}
.work__status::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
}
.work__status--soon::before {
  background: var(--color-accent);
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 0.35; }
  50%      { opacity: 1; }
}

/* 上线态：常亮的金点，不再是"还在等"的呼吸感 */
.work__status--live {
  border-color: var(--color-border-accent);
  color: var(--color-accent);
}
.work__status--live::before { background: var(--color-accent); }

/* ---- 可点的卡片 ----
   整张卡片都是链接的命中区，但可访问名仍然是标题文字（而不是一串
   "卡片 1 链接"）。做法是让标题里的 <a> 用 ::after 撑满整张卡片。 */
.work--live { cursor: pointer; }

.work__link {
  color: inherit;
  text-decoration: none;
  transition: color var(--dur-base) ease-out;
}

.work__link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  z-index: 1;
}

.work--live:hover .work__title,
.work--live:focus-within .work__title {
  color: var(--color-accent);
}

/* 键盘 Tab 到卡片时，给出和鼠标悬停一致的反馈 */
.work--live:focus-within {
  border-color: var(--color-border-accent);
  transform: translateY(-6px);
  box-shadow: var(--shadow-2), var(--glow-halo);
}
.work--live:focus-within::before { opacity: 1; }

/* 「开始玩 →」：不进链接文本，只给眼睛一个"这儿能点"的信号 */
.work__cta {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  margin-top: var(--space-1);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.14em;
  color: var(--color-accent);
}
.work__cta span {
  transition: transform var(--dur-base) var(--ease-out);
}
.work--live:hover .work__cta span,
.work--live:focus-within .work__cta span {
  transform: translateX(5px);
}

/* ======================================================================
   7. 作品区：按媒介分形态
   ----------------------------------------------------------------------
   游戏是"能玩的"，作品是"要看的"，所以不该共用同一张卡：
     工具  → 宽卡 + 一个明确动作（能带走的东西）
     图像  → 缩略图网格（3D 渲染、平面设计）
     视频  → 整块封面（剪辑）
     文字  → 条目 + 字数（小说、随笔）
   ====================================================================== */
.projects {
  display: grid;
  gap: var(--space-4);
}

/* ---------------------------- 工具 ------------------------------------ */
.tool {
  position: relative;          /* stretched link 的参照 */
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--space-5);
  padding: var(--space-5);
  background: linear-gradient(180deg, var(--color-surface), var(--ink-850));
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  transition: border-color var(--dur-base) ease-out;
}
.tool:hover { border-color: var(--color-border-accent); }

.tool__body { display: grid; gap: var(--space-2); }
.tool__kind,
.shot__kind,
.writ__kind {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.2em;
  color: var(--color-accent);
}
.tool__title,
.shot__title,
.film__title,
.writ__title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.3;
}
.tool__desc,
.film__desc,
.writ__desc {
  max-width: 48em;
  font-size: var(--fs-sm);
  line-height: 1.9;
  color: var(--color-muted);
}
.tool__meta,
.shot__note,
.film__len,
.writ__meta {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.1em;
  color: var(--color-faint);
}
.tool__aside { justify-self: end; }

/* 整卡可点，但读屏念出来的仍只有标题文字 —— 和作品卡同一套做法。
   ::after 的 inset:0 把命中区撑到整张卡。 */
.tool__link {
  color: inherit;
  text-decoration: none;
  transition: color var(--dur-base) ease-out;
}
.tool__link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  z-index: 1;
}
.tool:hover .tool__link,
.tool:focus-within .tool__link { color: var(--color-accent); }

.tool__cta {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.14em;
  color: var(--color-accent);
}
.tool__cta span {
  transition: transform var(--dur-base) var(--ease-out);
}
.tool:hover .tool__cta span,
.tool:focus-within .tool__cta span { transform: translateX(5px); }

/* ---------------------------- 图集 ------------------------------------ */
.shot {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}
.shot__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}
.shot__kind { color: var(--color-faint); }

/* 占位格用渐变而不是图片文件 —— 现在还没有真图，
   结构先立起来，以后换成 <img> 就行，尺寸比例不变。 */
.shot__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-2);
}
.shot__cell {
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1;
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  background:
    radial-gradient(120% 120% at 30% 20%,
      color-mix(in srgb, var(--moon-300) 9%, transparent), transparent 70%),
    var(--ink-850);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.1em;
  color: var(--color-faint);
  text-align: center;
  padding: var(--space-2);
  cursor: pointer;
  font-family: var(--font-mono);
  transition: border-color var(--dur-base) ease-out,
              transform var(--dur-base) var(--ease-out),
              background-color var(--dur-base) ease-out;
}
/* 可点开的格子：悬停时给一点回应，不然看不出能点 */
.shot__cell:hover {
  border-color: var(--color-border-accent);
  transform: translateY(-3px);
}
.shot__cell:active { transform: translateY(-1px); }

/* ---------------------------- 视频 ------------------------------------ */
.film {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: var(--space-5);
  align-items: center;
  padding: var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}
.film__frame {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background:
    radial-gradient(110% 110% at 50% 0%,
      color-mix(in srgb, var(--halo-300) 8%, transparent), transparent 65%),
    var(--ink-900);
  overflow: hidden;
}
/* 播放三角：纯 CSS，不引图标字体也不引图片 */
.film__play {
  width: 0;
  height: 0;
  border-left: 18px solid
    color-mix(in srgb, var(--color-accent) 82%, transparent);
  border-top: 12px solid transparent;
  border-bottom: 12px solid transparent;
  filter: drop-shadow(0 0 10px
    color-mix(in srgb, var(--color-accent) 34%, transparent));
}
.film__len {
  position: absolute;
  right: var(--space-3);
  bottom: var(--space-3);
  padding: 2px 8px;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--ink-950) 72%, transparent);
  color: var(--color-text-soft);
}
.film__body { display: grid; gap: var(--space-2); }

/* ---------------------------- 文字 ------------------------------------ */
.writ {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-5);
  background: linear-gradient(180deg, var(--color-surface), var(--ink-850));
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}
.writ__meta b {
  font-weight: 400;
  color: var(--color-accent);
  font-variant-numeric: tabular-nums;
}

/* 章节编号用 CSS counter，不用硬编码 ——
   分面之后「01 缘起 / 02 游戏 / 03 作品 / 04 关于」在亮面会显示成 02、03，
   在暗面显示成 01、04，两边都跳号。counter 只给**生成盒子的元素**计数，
   而 display:none 的不生成盒子，所以每一面自然从 01 重新开始；
   脚本不跑时没有 data-face，就按 DOM 顺序编号，同样连续。 */
[data-face] { counter-reset: faceSec; }
.eyebrow--num { counter-increment: faceSec; }
.eyebrow--num::before {
  content: counter(faceSec, decimal-leading-zero) " / ";
}

/* ======================================================================
   8. 亮面 / 暗面
   ----------------------------------------------------------------------
   底色不跟着翻 —— 底色一直是深空，变的只是月亮走到哪儿。
   隐藏规则挂在 [data-face] 上，而这个属性只由 scripts/face.js 写：
   脚本不跑 → 没有属性 → 两条规则都不生效 → 两面都显示，页面完整可读。
   ====================================================================== */
[data-face="lit"] [data-face="dark"],
[data-face="dark"] [data-face="lit"] { display: none; }

/* 导航里的分组同理 */
[data-face="lit"] .site-nav__group[data-face="dark"],
[data-face="dark"] .site-nav__group[data-face="lit"] { display: none; }

/* ---------------------------- 切换键 ---------------------------------- */
.facetoggle {
  position: relative;
  z-index: var(--z-content);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: 0 var(--space-2) 0 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  color: var(--color-faint);
  transition: color var(--dur-fast) ease-out;
}
.facetoggle:hover { color: var(--color-accent); }
.facetoggle__svg {
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 50%;
  transition: transform var(--dur-slow) var(--ease-out);
}
.facetoggle:hover .facetoggle__svg { transform: rotate(-18deg); }

/* 暗面时给月亮留一圈极弱的反照，不然空盘子在深空底上完全看不见 */
.facetoggle.is-dark .facetoggle__dark { fill: #131a2c; }
.facetoggle__face {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.16em;
  white-space: nowrap;
}

/* ---------------------------- 换面覆盖层 ------------------------------
   一轮月亮从满月走到新月。走到一半时内容换面 ——
   那时月亮正好在中间，两面都看不清，所以切换藏在中间。 */
.faceturn {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  pointer-events: none;
  opacity: 0;
  background: color-mix(in srgb, var(--ink-950) 82%, transparent);
  transition: opacity 180ms ease-out;
}
.faceturn[hidden] { display: none; }
.faceturn.is-on { opacity: 1; }
.faceturn__svg {
  width: min(78vmin, 78vh);
  height: min(78vmin, 78vh);
  overflow: visible;
}
.faceturn__dark { fill: #0a0e1a; }

/* ---------------------------- 联系栏 ---------------------------------- */
.contact {
  display: grid;
  gap: var(--space-3);
  justify-items: start;
  max-width: 40em;
}
.contact__item {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: linear-gradient(180deg, var(--color-surface), var(--ink-850));
  transition: border-color var(--dur-base) ease-out;
}
.contact__item:hover { border-color: var(--color-border-accent); }
.contact__kind {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.2em;
  color: var(--color-faint);
}
.contact__value {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  color: var(--color-accent);
}
.contact__hint {
  font-size: var(--fs-sm);
  line-height: 1.9;
  color: var(--color-faint);
}

/* ---------------------------- 灯箱 ------------------------------------
   图集点开看大图。结构先立起来 —— 现在还没有真图，格子会走「占位」分支，
   显示这个位置将来放什么；填上 data-full 之后同一套代码直接显示图片。 */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-header);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-rows: minmax(0, 1fr) auto;
  align-items: center;
  justify-items: center;
  gap: var(--space-4);
  padding: var(--space-5);
}
.lightbox[hidden] { display: none; }

.lightbox__scrim {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--ink-950) 94%, transparent);
  border: 0;
  cursor: zoom-out;
}
.lightbox__stage {
  position: relative;
  grid-column: 2;
  grid-row: 1;
  display: grid;
  gap: var(--space-3);
  justify-items: center;
  max-width: 100%;
  max-height: 100%;
  margin: 0;
}
/* 真实图片：留出 4:3 的框，加载完也不会跳版 */
.lightbox__img {
  display: block;
  max-width: min(84vw, 1000px);
  max-height: 74vh;
  width: auto;
  height: auto;
  border: 1px solid var(--color-border-accent);
  border-radius: var(--radius-md);
  background: var(--ink-900);
}
.lightbox__img[hidden] { display: none; }

/* 占位分支：没有 data-full 时显示这个，不假装有图。
   用 flex 而不是 grid —— grid 的 align-content 默认 stretch，
   会把两行文字平分整个高度，标题顶到上面、说明掉到下面，中间空一大片。 */
.lightbox__ph {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  width: min(84vw, 760px);
  aspect-ratio: 4 / 3;
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  background:
    radial-gradient(110% 110% at 30% 20%,
      color-mix(in srgb, var(--moon-300) 8%, transparent), transparent 70%),
    var(--ink-900);
  text-align: center;
  padding: var(--space-5);
}
/* p 自带上下 margin，不重置的话两行文字会被撑得很开 */
.lightbox__ph p,
.lightbox__cap { margin: 0; }
.lightbox__ph-title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  color: var(--color-text-soft);
}
.lightbox__ph-note {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.1em;
  line-height: 1.9;
  color: var(--color-faint);
}
.lightbox__ph[hidden] { display: none; }

.lightbox__cap {
  font-size: var(--fs-sm);
  color: var(--color-muted);
  text-align: center;
}
.lightbox__cap:empty { display: none; }

.lightbox__close,
.lightbox__nav {
  position: relative;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--color-border-strong);
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink-900) 72%, transparent);
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  color: var(--color-text-soft);
  cursor: pointer;
  transition: color var(--dur-fast) ease-out,
              border-color var(--dur-fast) ease-out;
}
.lightbox__close:hover,
.lightbox__nav:hover {
  color: var(--color-accent);
  border-color: var(--color-border-accent);
}
/* 上一张 / 下一张分居两侧；关闭键绝对定位到右上角，不占网格位 ——
   否则三列会被它挤掉一列。 */
.lightbox__nav--prev { grid-column: 1; grid-row: 1; }
.lightbox__nav--next { grid-column: 3; grid-row: 1; }
.lightbox__close {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  font-size: var(--fs-lg);
}

/* 计数放第二行居中 */
.lightbox__count {
  grid-column: 2;
  grid-row: 2;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.16em;
  color: var(--color-faint);
}
/* 只有一张图时不显示左右箭头 */
.lightbox[data-single="true"] .lightbox__nav { display: none; }

@media (max-width: 900px) {
  .works { grid-template-columns: 1fr; }
  .work:nth-child(n) { margin-top: 0; }

  /* 窄屏：工具卡与视频卡收成单列，缩略图网格降为两列 */
  .tool,
  .film { grid-template-columns: 1fr; }
  .tool__aside { justify-self: start; }
  .shot__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ======================================================================
   7. 关于 + 页脚
   ====================================================================== */
.about {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-7);
  align-items: start;
}

.about__body {
  display: grid;
  gap: var(--space-4);
}

.about__body p {
  font-size: var(--fs-base);
  line-height: 1.95;
  color: var(--color-text-soft);
}

/* 观测数据式的清单，左侧发丝线 */
.about__facts {
  display: grid;
  gap: 0;
  margin: 0;
  border-top: 1px solid var(--color-border);
}
.about__facts > div {
  display: grid;
  grid-template-columns: 7rem 1fr;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}
.about__facts dt {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-faint);
  padding-top: 4px;
}
.about__facts dd {
  font-size: var(--fs-sm);
  color: var(--color-text-soft);
}

@media (max-width: 900px) {
  .about { grid-template-columns: 1fr; gap: var(--space-6); }
}

.site-footer {
  position: relative;
  z-index: var(--z-content);
  border-top: 1px solid var(--color-border);
  padding: var(--space-6) var(--page-pad) var(--space-7);
  max-width: var(--page-max);
  margin: var(--space-7) auto 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.site-footer__brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--font-display);
  font-size: var(--fs-md);
  letter-spacing: 0.1em;
}

.site-footer__meta {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.14em;
  color: var(--color-faint);
  text-align: right;
  line-height: 2;
}

/* ======================================================================
   8. 入场编排
   一次编排好的序列（间隔 90ms）胜过满屏零散的微交互。
   只有首屏参与，滚动进入的区块交给 IntersectionObserver。
   ====================================================================== */
.hero__text > * {
  opacity: 0;
  animation: rise var(--dur-slow) var(--ease-out) forwards;
}
.hero__text > *:nth-child(1) { animation-delay: 120ms; }
.hero__text > *:nth-child(2) { animation-delay: 210ms; }
.hero__text > *:nth-child(3) { animation-delay: 300ms; }
.hero__text > *:nth-child(4) { animation-delay: 390ms; }
.hero__text > *:nth-child(5) { animation-delay: 480ms; }

@keyframes rise {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}

.hero__moon {
  opacity: 0;
  scale: 0.92;
  animation: moonIn 1.4s var(--ease-out) 80ms forwards;
}
@keyframes moonIn {
  from { opacity: 0; scale: 0.92; }
  to   { opacity: 1; scale: 1; }
}

/* 滚动进入的区块。
   只有确认脚本可用（html.js）时才初始隐藏 —— 否则禁用 JS 的用户
   会看到一整片空白页面。 */
.js .reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out);
}
.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .hero__text > *,
  .hero__moon {
    opacity: 1;
    scale: 1;
    animation: none;
  }
  .js .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .star { animation: none; opacity: 0.4; }
  .hero__cue-line::after { animation: none; transform: scaleX(1); }
  .work__status--soon::before { animation: none; opacity: 1; }
}

/* ======================================================================
   7. 404：月亮走到背面
   一页到底、居中、只有一轮看不见的月亮和两个出口。
   ====================================================================== */
.notfound {
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: var(--space-3);
  padding: var(--space-6) var(--space-5);
  text-align: center;
}

.notfound__moon {
  width: clamp(112px, 20vw, 176px);
  margin-bottom: var(--space-3);
}
.notfound__moon svg {
  display: block;
  width: 100%;
  height: auto;
}

.notfound h1 {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--color-text);
}

.notfound__lede {
  max-width: 32ch;
  font-size: var(--fs-base);
  line-height: 1.9;
  color: var(--color-muted);
}

.notfound__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  justify-content: center;
  margin-top: var(--space-4);
}
