/* site.css - 紫夜堂前台样式。
 *
 * 方向：把参考站的**排版语言**搬过来，配色走名字——
 *   巨字顶满屏宽 / 小号大写宽字距的眉标 / 药丸形元素 / 主视觉与巨字图层穿插。
 *   底色是近黑的夜蓝紫，强调色是亮紫。深色底还有个实际好处：
 *   游戏截图压在上面比浅色底更跳。
 *
 * 两个绕不开的约束，决定了这里的很多写法：
 *
 * 1. **中文没有压缩黑体**。参考站的张力来自极窄的 compressed sans，
 *    而系统中文字体里没有对应物（Google Fonts 大陆又取不到，不能挂）。
 *    所以巨字的气势改由字号 + 字重 + 负字距 + 字号逼近视口宽度来给，
 *    不去伪造一个不存在的字宽。Windows 上中文最粗只到雅黑 Bold(700)，
 *    因此巨字统一 700 而不是 900 —— 写 900 只会触发难看的合成加粗。
 *
 * 2. **药丸标签不是装饰**。参考站那几个飘着的 pill 是纯造型；这里换成带真实
 *    计数、可点击跳到对应栏目的入口。结构要编码信息，不然就是好看的噪音。
 */

/* ---------- tokens ---------- */
:root {
  --void:     #0d0a16;   /* 夜：近黑的蓝紫 */
  --void-2:   #15111f;   /* 压在夜上的一层：卡片 */
  --void-3:   #1e1830;   /* 再亮一档：分隔线、药丸描边 */
  --chalk:    #f2efff;   /* 冷白：巨字与主文本 */
  --muted:    #8a82a6;   /* 次级文字 */
  --violet:   #8b5cf6;   /* 强调：链接、当前位置、计数 */
  --violet-d: #6d28d9;
  --violet-w: rgba(139, 92, 246, .14);  /* 极淡的紫，用作悬停底 */

  --page: 1280px;
  --gap: clamp(16px, 2.5vw, 32px);

  /* 中文最粗到 Bold；把 PingFang/雅黑排在前面，别落到没有粗体的 SimHei 上 */
  --f-han: "PingFang SC", "Microsoft YaHei UI", "Microsoft YaHei",
           "Source Han Sans SC", "Noto Sans SC", system-ui, sans-serif;
  /* 拉丁小字用等宽：大写 + 宽字距时，等宽比比例字体更像"标记"而不是"句子" */
  --f-mono: ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--void);
  color: var(--chalk);
  font: 400 1rem/1.75 var(--f-han);
  overflow-wrap: break-word;
  /* 夜色里一点极淡的紫光，免得纯平涂显得死 */
  background-image:
    radial-gradient(60vw 40vw at 75% -10%, rgba(139, 92, 246, .16), transparent 60%),
    radial-gradient(40vw 30vw at 0% 100%, rgba(109, 40, 217, .10), transparent 60%);
  background-attachment: fixed;
}

img { max-width: 100%; display: block; }
a { color: var(--violet); text-decoration: none; }
a:hover { color: var(--chalk); }
:focus-visible { outline: 2px solid var(--violet); outline-offset: 3px; }

.shell { max-width: var(--page); margin: 0 auto; padding: 0 var(--gap); }

/* ---------- 小号大写标记：眉标、标签、计数 ---------- */
.mark {
  font: 500 .6875rem/1.4 var(--f-mono);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ---------- 药丸 ---------- */
.pill {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .5rem .95rem;
  border: 1px solid var(--void-3);
  border-radius: 999px;
  background: transparent;
  color: var(--chalk);
  font: 500 .8125rem/1 var(--f-han);
  white-space: nowrap;
  transition: background .18s, border-color .18s, color .18s;
}
.pill:hover { background: var(--violet-w); border-color: var(--violet); color: var(--chalk); }
.pill .n { font: 500 .6875rem/1 var(--f-mono); color: var(--violet); }
.pill.solid { background: var(--chalk); border-color: var(--chalk); color: var(--void); }
.pill.solid:hover { background: var(--violet); border-color: var(--violet); color: #fff; }
.pill.ghost { color: var(--muted); }

/* ---------- 顶栏 ---------- */
.topbar {
  display: flex;
  align-items: center;
  gap: clamp(.75rem, 2vw, 2rem);
  padding: 1.25rem 0 .5rem;
}
.logo {
  display: flex;
  align-items: center;
  gap: .55rem;
  font: 700 1.0625rem/1 var(--f-han);
  color: var(--chalk);
  letter-spacing: -.01em;
}
/* 标记：三道渐次收窄的竖条 + 一个紫点，像夜里的一线光。纯 CSS，不引图 */
.logo .glyph {
  display: inline-block;
  width: 1.15rem; height: 1.15rem;
  background:
    linear-gradient(var(--violet), var(--violet)) 0 50% / 3px 100% no-repeat,
    linear-gradient(var(--chalk), var(--chalk)) 7px 50% / 2px 66% no-repeat,
    linear-gradient(var(--muted), var(--muted)) 12px 50% / 2px 36% no-repeat;
}
.topnav { display: flex; gap: .25rem; flex-wrap: wrap; margin-left: auto; }
.topnav a {
  padding: .5rem .8rem;
  border-radius: 999px;
  font: 500 .8125rem/1 var(--f-han);
  color: var(--muted);
}
.topnav a:hover { color: var(--chalk); background: var(--violet-w); }
.topnav a[aria-current="page"] { color: var(--chalk); background: var(--void-3); }
.topbar .cta { display: flex; gap: .5rem; }

/* ---------- 首屏 ---------- */
.hero { padding: clamp(1.5rem, 4vw, 3rem) 0 clamp(2rem, 5vw, 4rem); }
.hero-head {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: .75rem;
}
.hero-head .tag { max-width: 32ch; }

/* 巨字与主视觉叠在同一个格子里。两种主视觉的叠法相反：
   后台传的照片压在字上（.hero-art），默认的月相图垫在字下（.hero-sky）——
   照片是实心的，压上去才有份量；月相图是暗底上的几个亮点，压上去只会糊掉字。 */
.hero-stage { position: relative; }

.wordmark {
  /* 巨字压在主视觉之上：月亮从笔画的缝隙里透出来，而不是被字挡成一块。
     没有 z-index 的话，定位过的 .hero-sky 会盖住本行内文字 */
  position: relative;
  z-index: 1;
  font-weight: 700;
  /* 字号按**字数**算而不是写死：站名从三个字改成四个字时，写死的 29vw 会直接溢出。
     --n 由 site.js 按标题长度注入。 */
  font-size: clamp(2.5rem, calc(90vw / var(--n, 3)), 26rem);
  line-height: .9;
  letter-spacing: -.045em;
  color: var(--chalk);
  white-space: nowrap;
  /* 上下按字号比例留白：line-height < 1 时字形会溢出行框，不留就会压住眉标和宣言。
     左边的负值把中文字面自带的边距吃掉，让字真正贴住版心。 */
  margin: .06em 0 .05em -.06em;
}
.wordmark .dim { color: var(--void-3); }

/* 主视觉：绝对定位压在巨字上；没有图时整块不渲染，首屏退化成纯排版 */
.hero-art {
  position: absolute;
  right: 0;
  bottom: -8%;
  width: min(46%, 30rem);
  pointer-events: none;
  /* 底部淡出，让图"长"进背景而不是贴一块方砖 */
  -webkit-mask-image: linear-gradient(to bottom, #000 72%, transparent);
  mask-image: linear-gradient(to bottom, #000 72%, transparent);
  filter: drop-shadow(0 24px 60px rgba(0, 0, 0, .55));
}

/* 默认主视觉：手写的夜空月相图（结构见 site.js 的 heroSky）。
   颜色一律取自变量，没有一个写死的色值——换主题色它自己跟着变。 */
.hero-sky {
  position: absolute;
  /* 不要负的 right：版心在宽屏是居中留白的，看不出来，可一到窄屏版心几乎顶满，
     伸出去的那点就成了整页的横向滚动条。 */
  right: 0;
  /* 顶边钉住、只往下伸。按 bottom 定位的话，舞台一矮图就整张往上爬——
     线上就栽在这儿：那会儿还没有作品，药丸一个都不出，舞台矮了一截，
     满月正好压住 SINCE 那行眉标。钉住顶边，栏目有没有都不会爬上去。
     宽高都给了，SVG 自己按 viewBox 等比缩进这个框，不会变形。 */
  top: -.5rem;
  height: calc(100% + 3.5rem);
  /* 跟着 vw 缩，而不是跟着版心的百分比：巨字的字号也是按 vw 算的，
     两者同步缩，图才一直和巨字一般高。按百分比的话，窄屏上巨字缩了、
     图没缩，月晕会一路顶到导航条上去。23rem 是上限，对齐巨字 19rem 的封顶。 */
  width: min(23rem, 26vw);
  z-index: 0;
  pointer-events: none;
  /* 满月那团光晕比 viewBox 大，默认的 overflow:hidden 会在右上角切出一条
     硬边——比没有光晕还难看。放它溢出去，本来就是要糊开的东西。 */
  overflow: visible;
}
/* 有月相图时把巨字收窄给它让位。
   满幅的巨字会把整张图盖死——只剩边角露出来，看着像渲染坏了，而不是穿插。
   收到 66vw 后，字仍然是首屏最大的东西，图完整露在右侧，两者只在
   最后一个字上叠一点点，穿插是**看得出来**的那种叠。 */
.hero-stage.has-sky .wordmark { font-size: clamp(2.5rem, calc(66vw / var(--n, 3)), 19rem); }
/* 满月背后的一团光晕：让右上角不是"贴了个圆"，而是有光源 */
.hero-sky .glow-a { stop-color: var(--violet); stop-opacity: .26; }
.hero-sky .glow-b { stop-color: var(--violet); stop-opacity: 0; }
/* 轨道用虚线：画的是月亮走过的路径，不是一根装饰弧 */
.hero-sky .orbit { stroke: var(--violet-d); stroke-width: 1.5; stroke-dasharray: 2 7; opacity: .45; }
.hero-sky .stars circle { fill: var(--muted); opacity: .5; }
/* 月面本体是背景色的圆（暗部），亮部叠在上面 */
.hero-sky .body { fill: var(--void-3); }
.hero-sky .lit { fill: var(--violet); }
/* 最后那轮满月亮到底，是整张图的落点，也是版面的视觉重心 */
.hero-sky .moon.full .lit { fill: var(--chalk); }

/* 七个相位依次亮起，像连着七个晚上。backwards 很关键：动画没开始前
   就按首帧渲染，万一动画被跳过也只是"直接是最终态"，不会整张图空着。 */
.hero-sky .moon {
  animation: moon-rise .9s cubic-bezier(.22, .61, .36, 1) backwards;
  animation-delay: calc(var(--d, 0) * .13s + .25s);
}
@keyframes moon-rise {
  from { opacity: 0; transform: translate(0, 16px); }
  to   { opacity: 1; transform: translate(0, 0); }
}

/* 模块入口排成一行放在巨字下面。
   参考站那几个 pill 是压在**图**上的；压在白色巨字上只会糊成一片。
   z-index 是必须的：不写会被上面定位过的 .hero-sky 盖住。 */
.hero-pills {
  position: relative;
  z-index: 1;
  display: flex;
  gap: .5rem;
  flex-wrap: wrap;
  margin-top: 1rem;
}

.hero-foot {
  display: flex;
  align-items: flex-end;
  gap: var(--gap);
  flex-wrap: wrap;
  margin-top: clamp(1rem, 3vw, 2.5rem);
}
.hero-claim { margin: 0 0 .9rem; max-width: 42ch; font-size: 1.0625rem; color: var(--chalk); }
.hero-tags { display: flex; gap: .5rem; flex-wrap: wrap; }

/* 名片：参考站右下那张深色卡 */
.card-me {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: .85rem;
  max-width: 22rem;
  padding: .8rem 1.1rem .8rem .8rem;
  border: 1px solid var(--void-3);
  border-radius: 1.5rem;
  background: var(--void-2);
}
.card-me img { width: 3rem; height: 3rem; border-radius: 1rem; object-fit: cover; flex: none; }
.card-me p { margin: 0; font-size: .8125rem; line-height: 1.6; color: var(--muted); }
.card-me strong { color: var(--chalk); font-weight: 600; }

/* ---------- 栏目 ---------- */
.section { padding: clamp(2rem, 5vw, 4rem) 0 0; }
.section-head {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  flex-wrap: wrap;
  border-top: 1px solid var(--void-3);
  padding-top: 1rem;
  margin-bottom: clamp(1rem, 2.5vw, 1.75rem);
}
.section-title {
  margin: 0;
  font: 700 clamp(1.75rem, 4.5vw, 3.25rem)/1.05 var(--f-han);
  letter-spacing: -.03em;
}
.section-head .mark { align-self: center; }
.section-more { margin-left: auto; font-size: .875rem; white-space: nowrap; }

/* ---------- 卡片网格 ---------- */
.grid {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fill, minmax(min(19rem, 100%), 1fr));
}
.card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--void-3);
  border-radius: 1.25rem;
  background: var(--void-2);
  overflow: hidden;
  transition: border-color .18s, transform .18s;
}
.card:hover { border-color: var(--violet); transform: translateY(-3px); }
.card-cover { aspect-ratio: 16 / 10; width: 100%; object-fit: cover; background: var(--void-3); }
.card-cover.icon {
  aspect-ratio: 1; width: 3.75rem; border-radius: 1rem;
  margin: 1.1rem 0 0 1.1rem; border: 1px solid var(--void-3);
}
.card-body { display: flex; flex-direction: column; gap: .5rem; padding: 1.1rem; flex: 1; }
.card-meta { display: flex; gap: .75rem; flex-wrap: wrap; }
.card-title { margin: 0; font: 600 1.125rem/1.4 var(--f-han); letter-spacing: -.01em; }
.card-title a { color: var(--chalk); }
.card-title a:hover { color: var(--violet); }
.card-sub { margin: 0; font-size: .875rem; color: var(--muted); }
.card-foot { margin-top: auto; padding-top: .75rem; font-size: .8125rem; }

/* ---------- 资讯：按日期排的行 ---------- */
.rows { border-top: 1px solid var(--void-3); }
.row {
  display: grid;
  grid-template-columns: 7rem 1fr auto;
  gap: 1rem;
  align-items: baseline;
  padding: 1.1rem .25rem;
  border-bottom: 1px solid var(--void-3);
  transition: background .18s;
}
.row:hover { background: var(--void-2); }
.row-date { font: 400 .75rem/1.6 var(--f-mono); color: var(--muted); letter-spacing: .06em; }
.row-title { font: 500 1.0625rem/1.5 var(--f-han); }
.row-title a { color: var(--chalk); }
.row-title a:hover { color: var(--violet); }
.row-sub { display: block; margin-top: .2rem; font-size: .8125rem; font-weight: 400; color: var(--muted); }

/* ---------- 详情页 ---------- */
.entry { padding: clamp(1.5rem, 4vw, 3rem) 0 0; }
.entry-title {
  margin: .75rem 0 0;
  font: 700 clamp(2rem, 6vw, 4.5rem)/1.02 var(--f-han);
  letter-spacing: -.04em;
}
.entry-sub { margin: .9rem 0 0; max-width: 46ch; font-size: 1.0625rem; color: var(--muted); }
.entry-cover { margin-top: var(--gap); border-radius: 1.25rem; border: 1px solid var(--void-3); }
.prose { max-width: 62ch; margin-top: var(--gap); font-size: 1.0625rem; color: #d9d4ea; }
.prose p { margin: 0 0 1.15em; }
.prose p:last-child { margin-bottom: 0; }

.shots { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr)); margin-top: var(--gap); }
.shot { margin: 0; border: 1px solid var(--void-3); border-radius: 1.25rem; overflow: hidden; background: var(--void-2); }
.shot figcaption { padding: .6rem .9rem; font-size: .8125rem; color: var(--muted); }

.pager {
  display: flex; justify-content: space-between; gap: 1.5rem;
  margin-top: clamp(2rem, 4vw, 3rem); padding-top: 1rem;
  border-top: 1px solid var(--void-3); font-size: .875rem;
}

/* ---------- 页脚：备案号是法定展示项，别删 ---------- */
.foot {
  margin-top: clamp(3rem, 7vw, 6rem);
  border-top: 1px solid var(--void-3);
  padding: 1.5rem 0 3rem;
  display: flex; flex-wrap: wrap; gap: .5rem 1.5rem; align-items: baseline;
  font-size: .8125rem; color: var(--muted);
}
.foot a { color: var(--muted); }
.foot a:hover { color: var(--violet); }
.foot .icp { font-family: var(--f-mono); font-size: .75rem; letter-spacing: .03em; }
.foot .spacer { margin-left: auto; }

/* ---------- 空状态：是行动提示，不是情绪 ---------- */
.empty {
  border: 1px dashed var(--void-3);
  border-radius: 1.25rem;
  padding: clamp(1.25rem, 3vw, 2rem);
  color: var(--muted);
  font-size: .9375rem;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- 入场：一次编排，不到处撒特效 ---------- */
@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes wipe { from { opacity: 0; transform: translateY(.12em) scaleY(.96); } to { opacity: 1; transform: none; } }
.wordmark { animation: wipe .7s cubic-bezier(.2, .75, .25, 1) both; }
.hero-head, .hero-foot { animation: rise .6s cubic-bezier(.2, .75, .25, 1) both .15s; }
.hero-art { animation: rise .8s cubic-bezier(.2, .75, .25, 1) both .1s; }
/* 药丸按 DOM 顺序依次进场；--d 由 site.js 注入，栏目少一个也不会留下空档 */
.hero-pills .pill {
  animation: rise .5s cubic-bezier(.2, .75, .25, 1) both;
  animation-delay: calc(var(--d, 0) * .1s + .45s);
}
.section { animation: rise .6s cubic-bezier(.2, .75, .25, 1) both; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ---------- 窄屏 ---------- */
@media (max-width: 860px) {
  /* 巨字与图在窄屏挤不下：照片退到巨字下方，占满一行 */
  .hero-art { position: static; width: 100%; margin-top: 1rem; bottom: auto; }
  .card-me { margin-left: 0; }
  .row { grid-template-columns: 1fr; gap: .3rem; }
  .row .mark { justify-self: start; }
}

/* 月相图的断点比照片晚：它只占右侧三分之一，巨字挤一挤还排得下，
   到 700 以下才真的没地方，退到巨字下面自成一块小插画。 */
@media (max-width: 700px) {
  .hero-stage.has-sky { display: flex; flex-direction: column; }
  /* 图不在旁边挤了，字号放大一档。不到 90vw 是因为版心两侧还有内边距，
     真按 90vw 排，最后一个字会被窗口切掉。 */
  .hero-stage.has-sky .wordmark { font-size: clamp(2.5rem, calc(78vw / var(--n, 3)), 19rem); }
  .hero-sky {
    position: static;
    height: auto;          /* 桌面端是钉在舞台上的固定高度，进了正常流就交回给 viewBox */
    order: 3;              /* DOM 里图在巨字**前面**（这样桌面端才垫得住），窄屏要挪到最后 */
    align-self: flex-end;  /* 靠右，接着巨字的走向，不在版心正中孤零零杵着 */
    width: min(62%, 15rem);
    margin-top: .75rem;
  }
}
@media (max-width: 560px) {
  .topnav { width: 100%; margin-left: 0; order: 3; }
  .topbar .cta { margin-left: auto; }
}
