/* ─────────────────────────────────────────────────────────────────
   styles.css — forest professional theme + original pixel RPG modal.
   No game-specific artwork is referenced or reproduced.
   ───────────────────────────────────────────────────────────────── */

/* Crawler-readable, human-invisible. Used to embed the prerendered EN
   mirror and the full-text archive bodies in the DOM so LLM agents /
   crawlers / link-preview bots can read everything, without making
   screen-reader users hear the same content twice. Pair with
   aria-hidden="true" on the element. */
.sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

:root {
  /* dark forest palette — anchored to the avatar (deep green coat, warm skin, black bg).
     Tuned for legibility, not edgy. */
  --bg:        oklch(0.13 0.012 150);
  --bg-soft:   oklch(0.17 0.014 148);
  --paper:     oklch(0.19 0.015 146);
  --paper-2:   oklch(0.22 0.018 145);
  --fg:        oklch(0.93 0.008 90);
  --fg-mute:   oklch(0.70 0.012 90);
  --fg-faint:  oklch(0.52 0.012 90);
  --border:    oklch(0.28 0.018 148);
  --border-strong: oklch(0.42 0.022 145);
  --accent:    oklch(0.78 0.10 140);   /* phosphor moss — legible on dark */
  --accent-soft: color-mix(in oklch, var(--accent) 14%, transparent);
  --warm:      oklch(0.80 0.10  70);

  --space-mul: 1;
  --max-w: 1080px;
  --gutter: 32px;

  /* fonts */
  --serif:   "Source Serif 4", "Noto Serif SC", "Songti SC", ui-serif, Georgia, serif;
  --sans:    "Inter Tight", "Source Sans 3", "Noto Sans SC", -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  --mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --display: var(--serif);
  --body:    var(--sans);

  color-scheme: dark;
}

/* type pairing tweaks */
:root[data-font="sans-only"]   { --display: var(--sans); }
:root[data-font="mono-accent"] { --display: var(--sans); --body: var(--sans); }

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--body);
  font-feature-settings: "ss01", "ss02", "kern", "calt";
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body {
  font-size: 16px; line-height: 1.6;
  /* Solid base color only. The radial "deep-in-the-woods" vignette is
     rendered as a fixed-position .atm-vignette div instead of background-
     attachment: fixed, which forced a full body repaint on every scroll
     frame and was the main cause of scroll jank in the leaves. */
  background: var(--bg);
  min-height: 100vh;
}

/* The vignette that used to live on body. Fixed-positioned so it never
   repaints during scroll; sits behind everything in the .site stacking
   context. */
.atm-vignette {
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(ellipse at 50% 30%,
      oklch(0.18 0.018 148) 0%,
      oklch(0.13 0.012 150) 55%,
      oklch(0.09 0.010 150) 100%);
}

/* ═════════════════════════════════════════════════════════════════
   ATMOSPHERE LAYERS — moonlight, fog, distant treeline, drifting
   leaves, idle breathing, card light-sweeps. All cosmetic, all
   pointer-events: none. Stacked back→front beneath .content.
   ═════════════════════════════════════════════════════════════════ */

/* Moonlight — a soft directional beam spilling from the upper-right.
   Uses a long blurred linear-gradient rotated into a cone shape so it
   reads as a directional shaft, not just a hotspot. */
.atm-moon {
  position: fixed;
  top: -260px;
  right: -320px;
  width: 880px;
  height: 1500px;
  pointer-events: none;
  z-index: 0;
  background: linear-gradient(
    202deg,
    rgba(225, 240, 255, 0.11) 0%,
    rgba(205, 225, 255, 0.06) 18%,
    rgba(170, 205, 245, 0.03) 45%,
    transparent 78%);
  transform: rotate(-14deg);
  transform-origin: top right;
  filter: blur(36px);
  mix-blend-mode: screen;
  opacity: 0.95;
}

/* Bottom fog — cool violet/blue mist hugging the bottom of the viewport,
   suggesting low ground vapour between the trees. Shorter than before so
   the treeline + leaf litter remain readable. */
.atm-fog {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  height: 38vh;
  pointer-events: none;
  z-index: 0;
  background:
    linear-gradient(
      to top,
      oklch(0.22 0.045 285 / 0.30) 0%,
      oklch(0.20 0.035 280 / 0.14) 35%,
      oklch(0.18 0.025 275 / 0.06) 65%,
      transparent 100%);
}

/* Distant treeline silhouettes — procedural SVG from atmosphere.jsx.
   Sits below the fog so the fog reads as drifting in front of the trees. */
.atm-trees {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  width: 100%;
  height: 240px;
  pointer-events: none;
  z-index: 0;
  opacity: 0.7;
}

/* Leaf litter — static fallen leaves along the bottom edge of the
   viewport. Visual cue for "this is the forest floor". The mask fades
   the upper portion so leaves taper off rather than ending sharply. */
.atm-litter {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  height: 110px;
  pointer-events: none;
  z-index: 1;
  mask: linear-gradient(to top, black 30%, transparent 100%);
  -webkit-mask: linear-gradient(to top, black 30%, transparent 100%);
}

/* Canopy — overhanging branches with leaves at the top corners.
   Left = dense / large, Right = sparse / smaller, intentionally
   asymmetric so the page doesn't read as a symmetric portal frame.
   Sits at z-index 0 (behind content). */
.atm-canopy {
  position: fixed;
  top: -10px;
  pointer-events: none;
  z-index: 0;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.5));
}
.atm-canopy-left  { left: -20px;  width: 320px; height: 220px; opacity: 0.78; }
.atm-canopy-right { right: -16px; width: 220px; height: 150px; opacity: 0.7; }

@media (max-width: 720px) {
  .atm-canopy-left  { width: 200px; height: 140px; opacity: 0.6;  left: -30px; }
  .atm-canopy-right { width: 140px; height:  96px; opacity: 0.55; right: -22px; }
  .atm-trees { height: 160px; opacity: 0.55; }
}

/* Idle "breathing" overlay — a soft vignette that fades in/out while the
   page is idle. Activated by .is-idle on <body> (set by atmosphere.jsx).
   Sits ABOVE content so it darkens the whole page edges-in during breath. */
.atm-pulse {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 3;
  background:
    radial-gradient(ellipse at 50% 40%, transparent 30%, rgba(0, 0, 0, 0.32) 100%);
  opacity: 0;
  transition: opacity 1.6s ease-in-out;
}
body.is-idle .atm-pulse {
  animation: idleBreathe 7.5s ease-in-out infinite;
}
@keyframes idleBreathe {
  0%, 100% { opacity: 0; }
  50%      { opacity: 0.55; }
}

/* Leaf drift — diagonal sway from one viewport edge to the other.
   Uses CSS rotation + translate keyframes for a swinging fall. */
@keyframes leafDriftR {
  0%   { transform: translate(0,        0)    rotate(0deg);   opacity: 0; }
  6%   { opacity: 0.85; }
  20%  { transform: translate(22vw,    7vh)  rotate(90deg); }
  40%  { transform: translate(46vw,   20vh)  rotate(170deg); }
  60%  { transform: translate(64vw,   14vh)  rotate(280deg); }
  80%  { transform: translate(86vw,   28vh)  rotate(370deg); }
  94%  { opacity: 0.85; }
  100% { transform: translate(110vw,  34vh)  rotate(540deg); opacity: 0; }
}
@keyframes leafDriftL {
  0%   { transform: translate(0,         0)   rotate(0deg);   opacity: 0; }
  6%   { opacity: 0.85; }
  20%  { transform: translate(-22vw,    7vh) rotate(-90deg); }
  40%  { transform: translate(-46vw,   20vh) rotate(-170deg); }
  60%  { transform: translate(-64vw,   14vh) rotate(-280deg); }
  80%  { transform: translate(-86vw,   28vh) rotate(-370deg); }
  94%  { opacity: 0.85; }
  100% { transform: translate(-110vw,  34vh) rotate(-540deg); opacity: 0; }
}

/* Card light-sweep — a brief warm streak passing diagonally across a
   card, simulating a firefly's bloom drifting over it. Triggered by
   atmosphere.jsx adding .is-sweep to a card. */
.is-sweep {
  position: relative;
  overflow: hidden;
}
.is-sweep::after {
  content: "";
  position: absolute;
  inset: -2px;
  pointer-events: none;
  z-index: 3;
  background: linear-gradient(
    115deg,
    transparent 30%,
    rgba(255, 232, 140, 0.10) 44%,
    rgba(255, 246, 200, 0.20) 50%,
    rgba(255, 232, 140, 0.10) 56%,
    transparent 70%);
  transform: translateX(-130%);
  animation: cardSweep 1.4s cubic-bezier(.45,.1,.55,.95) forwards;
  mix-blend-mode: screen;
}
@keyframes cardSweep {
  0%   { transform: translateX(-130%); }
  100% { transform: translateX(130%); }
}

/* Some cards don't natively have `position: relative` — guarantee it for the sweep */
.now-card,
.stat-card,
.work-item {
  position: relative;
}

@media (prefers-reduced-motion: reduce) {
  .atm-pulse,
  .is-sweep::after {
    animation: none !important;
  }
}

/* Fireflies canvas — fixed, never intercepts pointer.
   z-index 4 sits ABOVE everything except the sticky header.
   mix-blend-mode was removed — it forced a per-frame composite blend
   between the constantly-redrawn canvas and the scrolling content
   beneath, which compounded the scroll jank. The canvas draws bright
   enough on the dark background that screen blend isn't needed. */
.fireflies-canvas {
  position: fixed; inset: 0;
  width: 100vw; height: 100vh;
  pointer-events: none;
  z-index: 4;
}

/* tiny grain on the page so it isn't flat — subtle on dark */
body::before {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background-image:
    radial-gradient(rgba(255,255,255,.025) 1px, transparent 1px),
    radial-gradient(rgba(255,255,255,.015) 1px, transparent 1px);
  background-size: 3px 3px, 7px 7px;
  background-position: 0 0, 1px 2px;
  opacity: .7;
}

/* Body-text justification.
   The visible content stays left-anchored, but each line is justified
   so the right edge reads as a clean block — much calmer with mixed CN/EN. */
.about-para,
.now-text,
.work-summary,
.work-bullets li,
.project-body p,
.writing-intro,
.writing-bullet > span:last-child,
.edu-detail,
.other-body,
.skill-block {
  text-align: justify;
  text-justify: inter-character;
  hanging-punctuation: allow-end;
}

a { color: inherit; }
a:hover { color: var(--accent); }

button { font-family: inherit; }

/* ─────────────── Header ─────────────── */
.site-header {
  position: sticky; top: 0; z-index: 50;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center; gap: 24px;
  padding: 14px 28px;
  /* Was backdrop-filter: blur(14px) saturate(1.2) — that combo on a sticky
     element made the browser re-blur a band of pixels every scroll frame,
     which was the primary cause of scroll jank in the leaves. Replaced
     with a near-solid background which composites for free. */
  background: color-mix(in oklch, var(--bg) 94%, transparent);
  border-bottom: 1px solid var(--border);
}
.brand {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--display); font-size: 18px; font-weight: 500;
  text-decoration: none;
  letter-spacing: .01em;
}
.brand-mark { color: var(--accent); transform: translateY(-1px); }
.site-nav {
  display: flex; gap: 22px; justify-content: center;
  font-family: var(--mono); font-size: 12.5px;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--fg-mute);
}
.site-nav a { text-decoration: none; padding: 4px 0; border-bottom: 1px solid transparent; transition: color .2s, border-color .2s; }
.site-nav a:hover { color: var(--accent); border-bottom-color: var(--accent); }

.header-actions { display: flex; align-items: center; gap: 12px; }

.lang-toggle {
  display: inline-flex; border: 1px solid var(--border-strong);
  border-radius: 999px; padding: 2px; font-family: var(--mono); font-size: 12px;
  background: var(--paper);
}
.lang-toggle button {
  border: 0; background: transparent; padding: 4px 10px; cursor: pointer;
  border-radius: 999px; color: var(--fg-mute); letter-spacing: .04em;
  transition: background .2s, color .2s;
}
.lang-toggle button.active { background: var(--fg); color: var(--bg); }

.ghost-btn {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: 12px;
  padding: 6px 12px; border: 1px solid var(--border-strong);
  background: var(--paper); border-radius: 999px;
  color: var(--fg); cursor: pointer; letter-spacing: .03em;
  transition: background .2s, border-color .2s, transform .15s;
}
.ghost-btn:hover { background: var(--accent-soft); border-color: var(--accent); transform: translateY(-1px); }
.rpg-pixel-dot {
  display: inline-block; width: 8px; height: 8px; background: var(--accent);
  box-shadow:
    0 0 0 1px var(--bg),
    -3px 0 0 0 var(--accent),
    3px 0 0 0 var(--accent),
    0 3px 0 0 var(--accent),
    0 -3px 0 0 var(--accent);
  image-rendering: pixelated;
  margin-right: 2px;
}

/* ─────────────── Layout ─────────────── */
.site { position: relative; z-index: 1; }
/* .content sits ABOVE the atmosphere layers (moon/fog/trees) but BELOW the
   fireflies canvas (which uses mix-blend-mode: screen and should glow over text). */
.content { max-width: var(--max-w); margin: 0 auto; padding: 0 var(--gutter) 80px; position: relative; z-index: 2; }
.block {
  padding: calc(56px * var(--space-mul)) 0;
  border-top: 1px solid var(--border);
}
.block:first-of-type { border-top: 0; }

.kicker {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .12em;
  color: var(--fg-mute); margin-bottom: 28px; text-transform: uppercase;
}

/* ─────────────── Hero ─────────────── */
.hero { padding: calc(80px * var(--space-mul)) 0 calc(64px * var(--space-mul)); }
.hero-grid {
  display: grid; grid-template-columns: 1fr 240px; gap: 56px; align-items: start;
}
.status-pill {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 12px; color: var(--fg-mute);
  padding: 6px 12px; border: 1px solid var(--border-strong);
  border-radius: 999px; background: var(--paper);
  margin-bottom: 22px;
}
.dot-pulse {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 color-mix(in oklch, var(--accent) 60%, transparent);
  animation: pulse 2.4s ease-out infinite;
}
@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in oklch, var(--accent) 50%, transparent); }
  70%  { box-shadow: 0 0 0 10px color-mix(in oklch, var(--accent) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in oklch, var(--accent) 0%, transparent); }
}

.display {
  font-family: var(--display);
  font-size: clamp(40px, 6vw, 64px);
  font-weight: 500; line-height: 1.04; margin: 0 0 18px;
  letter-spacing: -0.012em;
}
.name-sep { color: var(--fg-faint); font-weight: 400; }
.name-en  { color: var(--fg-mute); font-weight: 400; font-style: italic; font-size: 0.78em; }

.tagline {
  font-family: var(--display);
  font-size: clamp(18px, 2.1vw, 22px);
  line-height: 1.45; color: var(--fg);
  max-width: 32ch;
  margin: 0 0 14px;
  text-wrap: pretty;
}

.rotator-line {
  font-family: var(--mono); font-size: 13px;
  color: var(--fg-mute); margin-bottom: 18px;
}
.rotator-prefix { opacity: .6; }
.caret {
  display: inline-block; width: 7px; height: 14px;
  background: var(--accent); margin-left: 2px; vertical-align: -2px;
  animation: blink 1s steps(2) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

.hero-meta {
  font-family: var(--mono); font-size: 12px; color: var(--fg-faint);
  margin-bottom: 24px; letter-spacing: .02em;
}
.hero-actions { display: flex; gap: 10px; flex-wrap: wrap; }

.contact-reveal {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--fg); color: var(--bg); border: 0;
  padding: 10px 18px; border-radius: 999px;
  font-family: var(--mono); font-size: 13px; letter-spacing: .03em;
  cursor: pointer;
  transition: background .2s, transform .15s;
}
.contact-reveal:hover { background: var(--accent); transform: translateY(-1px); }
.contact-reveal .lock { font-size: 14px; }

.pdf-btn { text-decoration: none; }
.pdf-btn:hover { color: var(--fg); }

.contact-list {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 13px; color: var(--fg);
}
.contact-list a { text-decoration: none; border-bottom: 1px solid var(--border-strong); }
.contact-list a:hover { color: var(--accent); border-color: var(--accent); }
.contact-list .dot { color: var(--fg-faint); }

.hero-right { display: flex; justify-content: flex-end; }
.portrait-slot {
  width: 220px; height: 220px;
  border: 1px solid var(--border-strong);
  background: #000;
  padding: 6px;
  position: relative;
}
.portrait-slot::before, .portrait-slot::after {
  content: ""; position: absolute; width: 10px; height: 10px;
  border: 1px solid var(--accent);
  pointer-events: none;
}
.portrait-slot::before { top: -1px; left: -1px; border-right: 0; border-bottom: 0; }
.portrait-slot::after  { bottom: -1px; right: -1px; border-left: 0; border-top: 0; }
.portrait-img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}

/* ─────────────── Section heads ─────────────── */

/* ─────────────── Now ─────────────── */
.now-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
}
.now-card {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 16px 18px;
  background: var(--paper);
  border: 1px solid var(--border);
  border-left: 2px solid var(--accent);
  transition: border-color .2s, transform .15s;
}
.now-card:hover { transform: translateX(2px); border-color: var(--accent); }
.now-bullet {
  color: var(--accent); font-size: 10px; margin-top: 8px; flex: 0 0 auto;
}
.now-text { font-size: 15px; line-height: 1.55; }

/* ─────────────── About ─────────────── */
.about-body { max-width: 64ch; }
.about-para {
  font-family: var(--display); font-size: 19px; line-height: 1.6;
  margin: 0 0 18px; color: var(--fg); text-wrap: pretty;
}
.about-para:last-child { color: var(--fg-mute); }

/* ─────────────── Work ─────────────── */
.work-list { display: flex; flex-direction: column; gap: 0; }
.work-item {
  border-top: 1px solid var(--border);
}
.work-item:last-child { border-bottom: 1px solid var(--border); }
.work-head {
  display: grid; grid-template-columns: 1fr auto; gap: 24px;
  width: 100%; text-align: left;
  padding: 20px 4px; background: transparent; border: 0; cursor: pointer;
  align-items: center;
  font-family: inherit; color: inherit;
  transition: background .2s;
}
.work-head:hover { background: color-mix(in oklch, var(--accent-soft) 60%, transparent); }
.work-org { font-family: var(--display); font-size: 20px; font-weight: 500; }
.work-role { font-size: 14px; color: var(--fg-mute); margin-top: 2px; font-style: italic; }
.work-head-right { display: flex; align-items: center; gap: 14px; flex-shrink: 0; }
.work-period { font-family: var(--mono); font-size: 12.5px; color: var(--fg-mute); white-space: nowrap; }
.work-tags { display: flex; gap: 6px; }
.tag {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .04em;
  text-transform: uppercase;
  padding: 3px 8px; border: 1px solid var(--border-strong);
  color: var(--fg-mute); border-radius: 2px;
  background: var(--paper);
}
.work-item.open .tag { color: var(--accent); border-color: var(--accent); }
.work-toggle {
  font-family: var(--mono); font-size: 18px; color: var(--fg-mute);
  width: 24px; text-align: center;
  transition: transform .3s ease, color .2s;
}
.work-item.open .work-toggle { color: var(--accent); }

.work-body {
  overflow: hidden;
  transition: max-height .5s cubic-bezier(.2,.7,.2,1);
}
.work-body-inner {
  padding: 0 4px 24px;
  display: flex; flex-direction: column; gap: 14px;
}
.work-summary { font-size: 15.5px; line-height: 1.6; margin: 0; color: var(--fg); }
.work-bullets { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 8px; }
.work-bullets li { font-size: 14.5px; line-height: 1.6; color: var(--fg); }
.work-bullets li::marker { color: var(--accent); }

.work-photos { display: flex; gap: 18px; flex-wrap: wrap; margin-top: 8px; }
.work-photos figure { margin: 0; max-width: 260px; }
.work-photos .photo-frame {
  position: relative; padding: 6px; background: var(--paper);
  border: 1px solid var(--border-strong);
}
.work-photos img { width: 100%; height: auto; display: block; }
.work-photos figcaption {
  font-family: var(--mono); font-size: 11px; line-height: 1.55;
  color: var(--fg-mute); margin-top: 8px;
}

/* ─────────────── Projects ─────────────── */
.projects-list { display: grid; grid-template-columns: 1fr; gap: 20px; }
.project-card {
  padding: 24px;
  background: var(--paper);
  border: 1px solid var(--border);
  transition: border-color .2s, transform .2s, box-shadow .2s;
  position: relative;
}
.project-card::before {
  content: ""; position: absolute; top: 0; left: 0; width: 3px; height: 100%;
  background: var(--accent); opacity: 0;
  transition: opacity .25s;
}
.project-card:hover { border-color: var(--border-strong); transform: translateY(-2px); }
.project-card:hover::before { opacity: 1; }
.project-head { margin-bottom: 12px; }
.project-name {
  font-family: var(--mono); font-size: 18px; font-weight: 500;
  margin: 0 0 4px; letter-spacing: .01em; color: var(--accent);
}
.project-tagline { font-size: 14px; color: var(--fg-mute); font-style: italic; }
.project-body p { margin: 0 0 10px; font-size: 14.5px; line-height: 1.6; }
.project-links {
  display: flex; gap: 18px; flex-wrap: wrap; margin-top: 12px;
  font-family: var(--mono); font-size: 12.5px;
}
.project-links a { text-decoration: none; color: var(--fg-mute); transition: color .2s; }
.project-links a:hover { color: var(--accent); }
.project-links .link-arrow { display: inline-block; transition: transform .2s; }
.project-links a:hover .link-arrow { transform: translateX(3px); }

/* ─────────────── Writing & influence ─────────────── */
.writing-intro {
  font-family: var(--display); font-size: 17px; line-height: 1.6;
  max-width: 56ch; color: var(--fg); margin: 0 0 28px;
}
.stats-row {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px;
  margin-bottom: 28px;
}
.stat-card {
  padding: 20px 18px; background: var(--paper); border: 1px solid var(--border);
}
.stat-value {
  font-family: var(--display); font-size: clamp(28px, 3.4vw, 40px);
  color: var(--accent); font-feature-settings: "tnum";
  font-weight: 500; line-height: 1;
}
.stat-label {
  font-family: var(--mono); font-size: 11.5px; color: var(--fg-mute);
  text-transform: uppercase; letter-spacing: .04em; margin-top: 10px;
}

.writing-bullets { display: flex; flex-direction: column; gap: 10px; max-width: 64ch; }
.writing-bullet { display: flex; gap: 14px; font-size: 15px; line-height: 1.6; }
.bul-tick { color: var(--accent); flex-shrink: 0; margin-top: 4px; }

/* ─────────────── Education ─────────────── */
.edu-list { display: flex; flex-direction: column; gap: 22px; }
.edu-item { padding: 4px 0; }
.edu-head {
  display: flex; justify-content: space-between; gap: 16px;
  align-items: baseline; margin-bottom: 4px;
}
.edu-school { font-family: var(--display); font-size: 18px; font-weight: 500; }
.edu-period { font-family: var(--mono); font-size: 12px; color: var(--fg-mute); white-space: nowrap; }
.edu-degree { font-size: 14px; color: var(--fg-mute); font-style: italic; margin-bottom: 6px; }
.edu-detail { font-size: 14.5px; line-height: 1.6; color: var(--fg); max-width: 64ch; }

/* ─────────────── Other ─────────────── */
.other-list { display: flex; flex-direction: column; gap: 22px; }
.other-head {
  display: flex; justify-content: space-between; gap: 16px;
  align-items: baseline; margin-bottom: 4px;
}
.other-org { font-family: var(--display); font-size: 17px; font-weight: 500; }
.other-period { font-family: var(--mono); font-size: 12px; color: var(--fg-mute); white-space: nowrap; }
.other-body { font-size: 14.5px; line-height: 1.6; color: var(--fg); max-width: 64ch; }

/* ─────────────── Awards & Skills ─────────────── */
.awards-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 40px;
}
.col-label {
  font-family: var(--mono); font-size: 11px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--fg-mute); margin-bottom: 14px;
}
.awards-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.awards-list li { display: flex; gap: 12px; font-size: 14px; line-height: 1.55; }
.award-year {
  font-family: var(--mono); color: var(--fg-mute); font-size: 12.5px;
  flex-shrink: 0; min-width: 38px; padding-top: 1px;
}
.skill-block { font-size: 14px; line-height: 1.7; margin: 0; color: var(--fg); }

/* ─────────────── Footer ─────────────── */
.site-footer {
  max-width: var(--max-w); margin: 0 auto; padding: 30px var(--gutter) 60px;
  display: flex; justify-content: space-between; align-items: center;
  flex-wrap: wrap; gap: 16px;
  font-family: var(--mono); font-size: 12px; color: var(--fg-mute);
  border-top: 1px solid var(--border);
  /* Footer is a sibling of .content, not a child — needs explicit
     stacking so atmosphere layers (trees, litter, fog) don't paint over it. */
  position: relative;
  z-index: 2;
}

/* ─────────────── RESPONSIVE ─────────────── */
@media (max-width: 720px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-right { justify-content: flex-start; }
  .now-grid { grid-template-columns: 1fr; }
  .stats-row { grid-template-columns: 1fr 1fr; }
  .awards-grid { grid-template-columns: 1fr; }
  .site-nav { display: none; }
  .site-header { grid-template-columns: auto 1fr; }
  .work-head { grid-template-columns: 1fr; }
  .work-head-right { justify-content: flex-start; flex-wrap: wrap; }
}

/* ═════════════════════════════════════════════════════════════════
   PIXEL RPG CHARACTER SHEET MODAL — original art only.
   ═════════════════════════════════════════════════════════════════ */

.rpg-overlay {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(8, 14, 12, 0.72);
  backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  animation: rpgFadeIn .25s ease;
  font-family: "DotGothic16", "VT323", ui-monospace, "Noto Sans SC", sans-serif;
}
@keyframes rpgFadeIn { from { opacity: 0; } to { opacity: 1; } }

.rpg-shell {
  --rpg-bg: #14201d;
  --rpg-bg-2: #1b2a26;
  --rpg-fg: #e8e3c8;
  --rpg-fg-mute: #a8b29a;
  --rpg-accent: #ffe27a;
  --rpg-accent-deep: #ffba3a;
  --rpg-rail: #4a5d4f;
  --rpg-danger: #ff6e6e;
  --rpg-ok: #7adf8a;

  width: min(880px, 100%); max-height: calc(100vh - 48px);
  background: var(--rpg-bg);
  color: var(--rpg-fg);
  position: relative;
  image-rendering: pixelated;
  /* Layered "stepped" pixel-style frame: nested 4px box-shadows form the border */
  box-shadow:
    0 0 0 4px var(--rpg-bg),
    0 0 0 8px var(--rpg-fg),
    0 0 0 12px var(--rpg-bg),
    0 0 0 14px var(--rpg-fg-mute),
    0 24px 0 -4px rgba(0,0,0,.5);
  animation: rpgPop .35s cubic-bezier(.2,.8,.3,1.2);
}
@keyframes rpgPop {
  0%   { transform: translateY(8px) scale(.96); opacity: 0; }
  100% { transform: none; opacity: 1; }
}

.rpg-statusbar {
  display: grid; grid-template-columns: auto 1fr auto;
  gap: 16px; align-items: center;
  padding: 12px 18px;
  background: linear-gradient(180deg, #233a31 0%, #1a2823 100%);
  border-bottom: 4px solid var(--rpg-fg-mute);
}
.rpg-hp { font-size: 14px; letter-spacing: .04em; display: flex; gap: 8px; align-items: baseline; }
.rpg-statkey { color: var(--rpg-accent); }
.rpg-statval { color: var(--rpg-fg); }
.rpg-title {
  text-align: center; font-size: 18px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--rpg-fg);
  font-family: "Press Start 2P", "Noto Sans SC", monospace;
  text-shadow: 2px 2px 0 #000;
}
/* Inside .rpg-title / .rpg-name, CJK runs use Noto Sans SC (full CJK coverage —
   DotGothic16 was missing 卡 and rendering at the wrong baseline). Bumped slightly
   and lifted so cap-height visually matches the Latin pixel glyphs next to it. */
.rpg-title .rpg-cjk,
.rpg-name .rpg-cjk {
  font-family: "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}
.rpg-title .rpg-cjk { font-size: 1.18em; vertical-align: -0.04em; }
.rpg-name  .rpg-cjk { font-size: 1.22em; vertical-align: -0.06em; }
.rpg-close {
  background: transparent; border: 0; color: var(--rpg-fg);
  font-family: inherit; font-size: 14px; cursor: pointer;
  padding: 4px 8px; letter-spacing: .04em;
  transition: color .15s;
}
.rpg-close:hover { color: var(--rpg-accent); }

.rpg-body {
  display: grid; grid-template-columns: 220px 1fr;
  gap: 0; padding: 18px;
}

.rpg-portrait {
  display: flex; flex-direction: column; gap: 14px;
  padding-right: 18px;
  border-right: 4px solid var(--rpg-fg-mute);
}
.rpg-portrait-frame {
  width: 100%; aspect-ratio: 1;
  background: var(--rpg-bg-2);
  box-shadow: inset 0 0 0 4px var(--rpg-fg-mute), inset 0 0 0 8px var(--rpg-bg);
  padding: 10px;
}
.rpg-portrait-inner {
  position: relative; width: 100%; height: 100%; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: #000;
}
.rpg-portrait-img {
  width: 100%; height: 100%; object-fit: cover;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  display: block;
}
.rpg-portrait-stripes {
  position: absolute; inset: 0;
  background-image: repeating-linear-gradient(
    45deg,
    rgba(255,226,122,.18) 0,
    rgba(255,226,122,.18) 4px,
    transparent 4px,
    transparent 12px);
  opacity: .8;
}
.rpg-portrait-label {
  position: relative; font-size: 11px; color: var(--rpg-fg-mute);
  letter-spacing: .04em; text-align: center;
}
.rpg-id { display: flex; flex-direction: column; gap: 4px; }
.rpg-name {
  font-family: "Press Start 2P", "Noto Sans SC", monospace;
  font-size: 14px; color: var(--rpg-accent); line-height: 1.3;
  text-shadow: 2px 2px 0 #000;
}
.rpg-class { font-size: 12px; color: var(--rpg-fg); }
.rpg-meta { font-size: 11px; color: var(--rpg-fg-mute); letter-spacing: .02em; }
.rpg-chips {
  display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px;
}
.rpg-chip {
  font-size: 10px; padding: 3px 6px;
  background: rgba(255,226,122,.12);
  color: var(--rpg-accent);
  letter-spacing: .04em;
  box-shadow: inset 0 0 0 1px rgba(255,226,122,.4);
}

/* Small "status" sub-panel below the chips on the left column.
   Fills the empty space that opens up because the right column is taller. */
.rpg-status-mini {
  margin-top: 10px;
  background: var(--rpg-bg-2);
  box-shadow: inset 0 0 0 2px var(--rpg-fg-mute);
  padding: 8px 10px;
  display: flex; flex-direction: column; gap: 5px;
}
.rpg-status-row {
  display: grid; grid-template-columns: 38px 1fr; gap: 8px; align-items: baseline;
  font-size: 11px; line-height: 1.3;
}
.rpg-status-k {
  color: var(--rpg-accent); letter-spacing: .06em;
  font-family: "Press Start 2P", monospace; font-size: 9px;
}
.rpg-status-v { color: var(--rpg-fg); }

.rpg-content {
  padding-left: 18px;
  display: flex; flex-direction: column; gap: 14px;
  min-width: 0;
}

.rpg-tabs {
  display: flex; gap: 4px;
  border-bottom: 4px solid var(--rpg-fg-mute);
  padding-bottom: 4px;
}
.rpg-tab {
  background: transparent; border: 0; color: var(--rpg-fg-mute);
  font-family: inherit; font-size: 11px; padding: 6px 7px; cursor: pointer;
  letter-spacing: .03em;
  transition: color .15s, background .15s;
  white-space: nowrap;
}
.rpg-tab:hover { color: var(--rpg-fg); }
.rpg-tab.active { color: var(--rpg-accent); background: var(--rpg-bg-2); }
.rpg-tab-arrow { color: var(--rpg-accent); margin-right: 2px; }

.rpg-tab-panel {
  /* Fixed height so the modal doesn't resize between tabs.
     Long tabs (inventory / trivia) scroll inside.
     scrollbar-gutter prevents a 1-frame width shift when the scrollbar appears/disappears. */
  height: 270px;
  overflow-y: auto; padding-right: 6px;
  scrollbar-gutter: stable;
}
/* Each tab body always rendered; only the active one shows. This preserves
   state (no remount → no replay of the StatBar fill animation). */
.rpg-tab-body { display: none; }
.rpg-tab-body.active { display: block; }
.rpg-tab-panel::-webkit-scrollbar { width: 8px; }
.rpg-tab-panel::-webkit-scrollbar-thumb { background: var(--rpg-fg-mute); }
.rpg-tab-panel::-webkit-scrollbar-track { background: var(--rpg-bg-2); }

.rpg-stats { display: flex; flex-direction: column; gap: 6px; }
.rpg-stat-row {
  display: grid; grid-template-columns: 130px 1fr 36px; gap: 12px;
  align-items: center;
  font-size: 12px; color: var(--rpg-fg);
}
.rpg-stat-label { letter-spacing: .04em; }
.rpg-stat-num { font-family: "Press Start 2P", monospace; font-size: 10px; color: var(--rpg-accent); text-align: right; }

.rpg-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 7px; }
.rpg-list li { font-size: 13px; color: var(--rpg-fg); display: flex; gap: 10px; align-items: baseline; line-height: 1.5; }
.rpg-list-glyph { color: var(--rpg-accent); flex-shrink: 0; }

.rpg-trivia { display: flex; flex-direction: column; gap: 12px; }
.rpg-trivia-row { display: flex; flex-direction: column; gap: 4px; }
.rpg-trivia-k {
  font-size: 12px; color: var(--rpg-accent);
  letter-spacing: .04em; display: flex; gap: 8px; align-items: baseline;
}
.rpg-trivia-v {
  font-size: 12.5px; color: var(--rpg-fg); line-height: 1.6;
  padding-left: 18px;
}

.rpg-motto-note {
  display: block; margin-top: 6px;
  font-size: 11px; color: var(--rpg-fg-mute); letter-spacing: .02em;
}

/* SAVES tab */
.rpg-saves { display: flex; flex-direction: column; gap: 12px; }
.rpg-save-row {
  background: var(--rpg-bg-2);
  box-shadow: inset 0 0 0 2px var(--rpg-fg-mute);
  padding: 8px 12px;
  display: flex; flex-direction: column; gap: 3px;
}
.rpg-save-head {
  display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
}
.rpg-save-slot {
  font-family: "Press Start 2P", monospace; font-size: 9px;
  color: var(--rpg-accent); letter-spacing: .04em;
}
.rpg-save-place { font-size: 13px; color: var(--rpg-fg); }
.rpg-save-period { font-size: 11px; color: var(--rpg-fg-mute); margin-left: auto; }
.rpg-save-playtime {
  font-size: 10px; color: var(--rpg-fg-mute); letter-spacing: .02em;
}
.rpg-save-body { font-size: 12px; color: var(--rpg-fg); line-height: 1.55; }
.rpg-save-note {
  font-size: 10.5px; color: var(--rpg-fg-mute); font-style: italic;
  line-height: 1.55; padding: 0 4px;
}

/* BOOKMARKS tab */
.rpg-bookmarks {
  display: grid; grid-template-columns: 1fr; gap: 8px;
}
.rpg-bookmark-row {
  display: grid; grid-template-columns: 120px 1fr; gap: 12px; align-items: baseline;
  font-size: 12px; line-height: 1.5;
}
.rpg-bookmark-k {
  color: var(--rpg-accent); font-size: 11px;
  letter-spacing: .02em;
  display: flex; gap: 6px; align-items: baseline;
}
.rpg-bookmark-v { color: var(--rpg-fg); }

/* COMPANIONS / PARTY tab */
.rpg-companions { display: flex; flex-direction: column; gap: 7px; }
.rpg-companion-row {
  display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap;
  font-size: 12px; line-height: 1.5; padding-left: 2px;
}
.rpg-companion-type { color: var(--rpg-fg-mute); }
.rpg-companion-name { color: var(--rpg-accent); font-weight: 500; }
.rpg-companion-note {
  color: var(--rpg-fg); font-size: 11.5px;
}

/* Mojibake glitch — used on the "AI 自设" row's note as a typographic in-joke.
   RGB-split + flicker; reduced-motion users get just the color treatment. */
.rpg-mojibake {
  color: #ff6b6b;
  font-family: "Press Start 2P", "Noto Sans SC", monospace;
  font-size: 10.5px;
  letter-spacing: .04em;
  text-shadow:
    1px 0 0 #5ad7ff,
    -1px 0 0 #ff5a5a,
    0 0 6px rgba(255,90,90,.35);
  animation: mojibake-flicker 2.4s steps(1, end) infinite;
  position: relative;
  padding: 0 2px;
}
/* Brackets of indeterminacy — symbols flanking the mojibake to underscore that
   these personae resist definition. Cycle through ? ¿ ※ ⁇ ◌ ⌇ on a different beat
   than the main flicker so the whole thing looks unstable. */
.rpg-mojibake::before,
.rpg-mojibake::after {
  display: inline-block;
  color: #ffb86b;
  font-family: "Press Start 2P", "Noto Sans SC", monospace;
  font-size: 10px;
  text-shadow: 1px 0 0 #5ad7ff, -1px 0 0 #ff5a5a;
  animation: mojibake-symbols 1.6s steps(1, end) infinite;
  opacity: .9;
}
.rpg-mojibake::before {
  content: "? ¿ ⁇";
  margin-right: 8px;
  letter-spacing: .1em;
}
.rpg-mojibake::after {
  content: "⁇ ¿ ?";
  margin-left: 8px;
  letter-spacing: .1em;
  animation-delay: -.8s;        /* offset so left/right don't blink in sync */
  animation-duration: 1.9s;
}
@keyframes mojibake-flicker {
  0%, 18%, 22%, 41%, 44%, 67%, 70%, 100% { opacity: 1; transform: translateX(0); }
  19%  { opacity: .35; transform: translateX(1px); }
  20%  { opacity: 1;   transform: translateX(-1px); }
  42%  { opacity: .25; transform: translateX(-1px); }
  43%  { opacity: 1;   transform: translateX(1px); }
  68%  { opacity: .5;  transform: translateX(0); }
  69%  { opacity: 1;   transform: translateX(-1px); letter-spacing: .12em; }
}
@keyframes mojibake-symbols {
  0%   { content: "? ¿ ⁇"; transform: translateY(0);    opacity: .9; }
  20%  { content: "※ ⌇ ◌"; transform: translateY(-1px); opacity: .6; }
  35%  { content: "⁇ ? ¿"; transform: translateY(1px);  opacity: 1;  }
  55%  { content: "◌ ※ ⁇"; transform: translateY(0);    opacity: .3; }
  70%  { content: "¿ ⁇ ?"; transform: translateY(-1px); opacity: 1;  }
  85%  { content: "⌇ ◌ ※"; transform: translateY(1px);  opacity: .7; }
  100% { content: "? ¿ ⁇"; transform: translateY(0);    opacity: .9; }
}
@media (prefers-reduced-motion: reduce) {
  .rpg-mojibake,
  .rpg-mojibake::before,
  .rpg-mojibake::after { animation: none; }
}

.rpg-dialog {
  margin-top: auto;
  background: var(--rpg-bg-2);
  box-shadow: inset 0 0 0 3px var(--rpg-fg), inset 0 0 0 6px var(--rpg-bg-2);
  padding: 12px 16px 14px;
  position: relative;
  cursor: pointer;
  transition: box-shadow .15s;
}
.rpg-dialog:hover { box-shadow: inset 0 0 0 3px var(--rpg-accent), inset 0 0 0 6px var(--rpg-bg-2); }
.rpg-dialog-head {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 4px;
}
.rpg-dialog-name {
  font-size: 12px; color: var(--rpg-accent);
  letter-spacing: .04em;
}
.rpg-dialog-counter {
  font-family: "Press Start 2P", monospace; font-size: 9px;
  color: var(--rpg-fg-mute); letter-spacing: .04em;
}
.rpg-dialog-text {
  font-size: 13px; line-height: 1.55; color: var(--rpg-fg);
  /* subtle fade-in when motto changes */
  animation: rpgMottoIn .35s ease;
}
@keyframes rpgMottoIn {
  from { opacity: 0; transform: translateY(2px); }
  to   { opacity: 1; transform: none; }
}
.rpg-chev {
  display: inline-block; margin-left: 6px; color: var(--rpg-accent);
  animation: rpgBlink 0.9s steps(2) infinite;
}
@keyframes rpgBlink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }

.rpg-hint {
  padding: 8px 18px;
  background: var(--rpg-bg-2);
  border-top: 4px solid var(--rpg-fg-mute);
  font-size: 11px; color: var(--rpg-fg-mute);
  display: flex; justify-content: space-between; gap: 14px;
  letter-spacing: .04em;
}
.rpg-hint-mid { flex: 1; text-align: center; }
.rpg-press { color: var(--rpg-accent); }

/* ═════════════════════════════════════════════════════════════════
   ARCHIVE — writing collections (xiaohongshu posts, four themes)
   ═════════════════════════════════════════════════════════════════ */

.archive-block { }

.archive-intro {
  font-family: var(--display);
  font-size: 17px; line-height: 1.65;
  color: var(--fg);
  max-width: 60ch;
  margin: 0 0 28px;
  text-wrap: pretty;
  text-align: justify;
  text-justify: inter-character;
  hanging-punctuation: allow-end;
}

.archive-stats {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px;
  margin-bottom: 42px;
}

/* ─── Xiaohongshu profile card (between intro and stats) ─── */
.xhs-card {
  --xhs-red: oklch(0.65 0.18 25);
  margin: 4px 0 32px;
  padding: 18px 22px 20px;
  background: var(--paper);
  border: 1px solid var(--border);
  border-left: 2px solid var(--xhs-red);
  max-width: 64ch;
  position: relative;
}
.xhs-card-head {
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap;
  padding-bottom: 12px;
  margin-bottom: 14px;
  border-bottom: 1px dashed var(--border);
}

/* Two-column body: avatar on left, bio on right */
.xhs-card-body {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 18px;
  align-items: start;
}

/* Avatar — chunky framed slot with corner ticks in xhs-red.
   Echoes the pixel-RPG portrait aesthetic elsewhere on the site, tinted red. */
.xhs-avatar {
  position: relative;
  width: 88px;
  height: 88px;
  flex: 0 0 auto;
}
.xhs-avatar-frame {
  position: relative;
  width: 100%;
  height: 100%;
  padding: 4px;
  background: #000;
  box-shadow:
    0 0 0 1px var(--xhs-red),
    0 0 0 4px #000,
    0 0 0 5px color-mix(in oklch, var(--xhs-red) 50%, transparent);
  overflow: hidden;
}
.xhs-avatar-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Tick marks at the four corners — stacked offset to give a screen-burn glow */
.xhs-avatar-corner {
  position: absolute;
  width: 8px; height: 8px;
  border: 1.5px solid var(--xhs-red);
  pointer-events: none;
}
.xhs-avatar-corner-tl { top: -6px;    left: -6px;    border-right: 0; border-bottom: 0; }
.xhs-avatar-corner-tr { top: -6px;    right: -6px;   border-left:  0; border-bottom: 0; }
.xhs-avatar-corner-bl { bottom: -6px; left: -6px;    border-right: 0; border-top:    0; }
.xhs-avatar-corner-br { bottom: -6px; right: -6px;   border-left:  0; border-top:    0; }
.xhs-mark {
  color: var(--xhs-red);
  font-size: 12px;
  line-height: 1;
}
.xhs-label {
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: .04em;
  color: var(--fg-mute);
}
.xhs-platform { color: var(--fg); }
.xhs-sep { color: var(--fg-faint); }
.xhs-handle { color: var(--xhs-red); }
.xhs-link {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--fg-mute);
  text-decoration: none;
  padding: 4px 10px;
  border: 1px solid var(--border-strong);
  border-radius: 2px;
  transition: color .15s, border-color .15s, background .15s;
}
.xhs-link:hover {
  color: var(--xhs-red);
  border-color: var(--xhs-red);
  background: color-mix(in oklch, var(--xhs-red) 8%, transparent);
}
.xhs-link-arrow { transition: transform .15s; }
.xhs-link:hover .xhs-link-arrow { transform: translateX(3px); }

.xhs-bio {
  display: flex; flex-direction: column; gap: 6px;
}
.xhs-bio-line {
  margin: 0;
  font-family: var(--body);
  font-size: 14px;
  line-height: 1.65;
  color: var(--fg);
  text-wrap: pretty;
}
.xhs-bio-warn {
  color: var(--fg-mute);
  font-size: 13.5px;
}
.xhs-bio-key {
  color: var(--xhs-red);
  font-weight: 500;
  font-family: var(--display);
}
.xhs-bio-quote {
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px dashed var(--border);
  font-family: var(--display);
  font-size: 14px;
  line-height: 1.7;
  color: var(--fg-mute);
  font-style: italic;
  text-wrap: pretty;
}

@media (max-width: 720px) {
  .archive-stats { grid-template-columns: 1fr; }
  .xhs-card { padding: 16px 16px 18px; }
  .xhs-link { margin-left: 0; }
  .xhs-card-body { grid-template-columns: 1fr; gap: 16px; justify-items: start; }
  .xhs-avatar { width: 72px; height: 72px; }
}

.archive-collections {
  display: flex; flex-direction: column;
  gap: 44px;
  margin-bottom: 48px;
}

.archive-col {
  --col-accent: var(--accent);
  position: relative;
  padding: 26px 4px 22px 22px;
  border-top: 1px solid var(--border);
  border-left: 1px solid var(--border);
  background:
    linear-gradient(180deg,
      color-mix(in oklch, var(--col-accent) 4%, transparent) 0%,
      transparent 38%);
}
.archive-col::before {
  /* slim color rail on the left, the discipline tint */
  content: "";
  position: absolute; top: 0; left: -1px; bottom: 0;
  width: 2px; background: var(--col-accent);
  opacity: .55;
}

.archive-col-head {
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
}
.archive-col-mark {
  width: 9px; height: 9px;
  background: var(--col-accent);
  flex: 0 0 auto;
  /* tiny "phosphor" pixel — echoes the brand-mark in the header */
  box-shadow:
    0 0 0 2px color-mix(in oklch, var(--col-accent) 30%, transparent);
  transform: translateY(1px);
}
.archive-col-name {
  font-family: var(--display);
  font-size: 28px; font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--fg);
}
.archive-col-cn { color: var(--fg); }
.archive-col-sep { color: var(--fg-faint); font-weight: 400; padding: 0 4px; }
.archive-col-roman {
  color: var(--col-accent);
  font-style: italic;
  font-weight: 400;
  font-size: 0.74em;
  letter-spacing: 0.01em;
}
.archive-col-count {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--fg-mute);
  letter-spacing: .04em;
  display: flex; align-items: baseline; gap: 3px;
}
.ac-real  { color: var(--col-accent); font-weight: 500; }
.ac-slash { color: var(--fg-faint); }
.ac-total { color: var(--fg-mute); }
.ac-unit  { color: var(--fg-faint); margin-left: 4px; }

.archive-col-meta {
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fg-faint);
}
.archive-col-discipline { }

.archive-col-gloss {
  margin: 10px 0 18px;
  font-family: var(--display);
  font-size: 14.5px; line-height: 1.55;
  color: var(--fg-mute);
  max-width: 56ch;
  text-wrap: pretty;
}

/* Horizontal rail of post cards. Snap-scrolls. */
.archive-rail {
  display: flex; gap: 14px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding: 4px 18px 14px 0;
  margin-right: -18px;  /* let cards bleed to viewport edge */
  scrollbar-width: thin;
  scrollbar-color: var(--col-accent) transparent;
}
.archive-rail::-webkit-scrollbar { height: 8px; }
.archive-rail::-webkit-scrollbar-thumb {
  background: color-mix(in oklch, var(--col-accent) 40%, transparent);
  border-radius: 4px;
}
.archive-rail::-webkit-scrollbar-track { background: transparent; }

/* Post card */
.post-card {
  flex: 0 0 200px;
  scroll-snap-align: start;
  display: flex; flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--border);
  padding: 0;
  cursor: pointer;
  font-family: inherit;
  color: inherit;
  text-align: left;
  transition: border-color .2s, transform .2s, box-shadow .2s;
  position: relative;
  overflow: hidden;
}
.post-card:not(:disabled):hover {
  border-color: var(--col-accent);
  transform: translateY(-2px);
  box-shadow:
    0 8px 0 -4px color-mix(in oklch, var(--col-accent) 30%, transparent),
    0 0 0 0 transparent;
}
.post-card:disabled {
  cursor: default;
  opacity: 0.5;
}

.post-card-cover {
  position: relative;
  aspect-ratio: 3 / 4;
  width: 100%;
  background: #000;
  overflow: hidden;
  border-bottom: 1px solid var(--border);
}
.post-card-cover img {
  width: 100%; height: 100%;
  object-fit: contain;   /* preserve original framing — don't crop */
  display: block;
  transition: transform .4s ease;
}
.post-card:not(:disabled):hover .post-card-cover img {
  transform: scale(1.03);
}

/* Text-only post: an editorial face — large initial + roman discipline */
.post-card-textface {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 8px;
  background:
    repeating-linear-gradient(
      0deg,
      color-mix(in oklch, var(--col-accent) 4%, transparent) 0,
      color-mix(in oklch, var(--col-accent) 4%, transparent) 1px,
      transparent 1px,
      transparent 6px);
}
.ptf-mark {
  font-family: var(--display);
  font-size: 96px;
  line-height: 1;
  color: color-mix(in oklch, var(--col-accent) 70%, var(--fg-faint));
  font-weight: 500;
}
.ptf-roman {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fg-mute);
}

/* Placeholder 9-grid preview (when gallery has no real cover) */
.post-card-9grid {
  position: absolute; inset: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 2px;
  padding: 14px;
  background: color-mix(in oklch, var(--col-accent) 5%, var(--bg-soft));
}
.post-card-9cell {
  background: color-mix(in oklch, var(--col-accent) 12%, var(--paper-2));
  border: 1px solid color-mix(in oklch, var(--col-accent) 18%, transparent);
}

/* Gallery badge ("9") in upper-right of cover */
.post-card-badge {
  position: absolute; top: 8px; right: 8px;
  font-family: var(--mono); font-size: 10px;
  padding: 3px 7px;
  background: color-mix(in oklch, var(--col-accent) 88%, var(--bg));
  color: var(--bg);
  letter-spacing: .05em;
  font-weight: 600;
}

/* Placeholder stamp */
.post-card-stamp {
  position: absolute; top: 12px; left: 12px;
  font-family: var(--mono); font-size: 10px;
  padding: 3px 7px;
  border: 1px dashed var(--fg-faint);
  color: var(--fg-faint);
  letter-spacing: .08em; text-transform: uppercase;
  background: color-mix(in oklch, var(--bg) 70%, transparent);
}

.post-card-body {
  padding: 12px 14px 14px;
  display: flex; flex-direction: column; gap: 6px;
  flex: 1;
}
.post-card-title {
  font-family: var(--display);
  font-size: 15px; line-height: 1.4;
  color: var(--fg);
  font-weight: 500;
  /* clamp to 3 lines so cards stay even */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
}
.post-card:not(:disabled):hover .post-card-title {
  color: var(--col-accent);
}
.post-card.is-placeholder .post-card-title {
  color: var(--fg-mute);
  font-style: italic;
}
.post-card-kind {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-top: auto;
}

/* Influence tail */
.archive-influence {
  border-top: 1px solid var(--border);
  padding-top: 28px;
  margin-top: 8px;
}
.archive-influence .col-label {
  margin-bottom: 16px;
  letter-spacing: .08em;
}

/* ─────────────────────────────────────────────────────────────────
   READER MODAL — long-form essay overlay
   ───────────────────────────────────────────────────────────────── */

.reader-overlay {
  position: fixed; inset: 0; z-index: 250;
  background: color-mix(in oklch, var(--bg) 78%, rgba(0,0,0,0.4));
  backdrop-filter: blur(8px) saturate(1.1);
  -webkit-backdrop-filter: blur(8px) saturate(1.1);
  display: flex;
  align-items: stretch; justify-content: center;
  padding: 0;
  animation: readerFadeIn .25s ease;
}
@keyframes readerFadeIn { from { opacity: 0; } to { opacity: 1; } }

.reader-shell {
  --col-accent: var(--accent);
  position: relative;
  width: 100%;
  max-width: 880px;
  background: var(--bg-soft);
  border-left: 1px solid var(--border);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  animation: readerSlideUp .45s cubic-bezier(.2,.8,.2,1);
  box-shadow:
    0 -1px 0 var(--col-accent),
    0 24px 64px rgba(0,0,0,.45);
}
@keyframes readerSlideUp {
  from { transform: translateY(24px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}

/* Top progress bar */
.reader-progress {
  position: absolute; top: 0; left: 0;
  height: 2px; width: 100%;
  background: var(--col-accent);
  transform-origin: 0 50%;
  transform: scaleX(0);
  transition: transform .1s linear;
  z-index: 2;
}

.reader-head {
  position: sticky; top: 0;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 24px;
  background: color-mix(in oklch, var(--bg-soft) 92%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
  z-index: 1;
}
.reader-head-left {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--fg-mute);
  letter-spacing: .04em;
}
.reader-col-mark {
  width: 8px; height: 8px;
  background: var(--col-accent);
  flex: 0 0 auto;
  box-shadow: 0 0 0 2px color-mix(in oklch, var(--col-accent) 30%, transparent);
}
.reader-col-cn { color: var(--fg); }
.reader-col-sep { color: var(--fg-faint); }
.reader-col-roman { color: var(--col-accent); font-style: italic; }

.gallery-head-title {
  color: var(--fg);
  margin-left: 6px;
}

.reader-close {
  display: inline-flex; align-items: center; gap: 8px;
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--fg-mute);
  padding: 6px 10px;
  font-family: var(--mono);
  font-size: 12px; letter-spacing: .04em;
  cursor: pointer;
  transition: border-color .15s, color .15s;
  border-radius: 2px;
}
.reader-close:hover { color: var(--col-accent); border-color: var(--col-accent); }
.reader-close-esc {
  font-size: 9px; opacity: .7; letter-spacing: .12em;
}

.reader-scroll {
  flex: 1;
  overflow-y: auto;
  scrollbar-gutter: stable;
}
.reader-scroll::-webkit-scrollbar { width: 10px; }
.reader-scroll::-webkit-scrollbar-thumb {
  background: color-mix(in oklch, var(--col-accent) 35%, transparent);
  border-radius: 4px;
}
.reader-scroll::-webkit-scrollbar-track { background: transparent; }

.reader-article {
  max-width: 640px;
  margin: 0 auto;
  padding: 56px 32px 96px;
}

.reader-title {
  font-family: var(--display);
  font-size: clamp(28px, 3.4vw, 40px);
  line-height: 1.18;
  font-weight: 500;
  color: var(--fg);
  margin: 0 0 12px;
  letter-spacing: -0.012em;
  text-wrap: balance;
}
.reader-sub {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fg-mute);
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 28px;
}
.reader-sub span { color: var(--col-accent); }

.reader-cover {
  margin: 0 -8px 36px;
  position: relative;
  background: #000;
  border: 1px solid var(--border-strong);
  padding: 6px;
}
.reader-cover img {
  display: block;
  width: 100%; height: auto;     /* natural aspect ratio, no crop */
  object-fit: contain;
}

.reader-body p {
  font-family: var(--display);
  font-size: 18px;
  line-height: 1.85;
  color: var(--fg);
  margin: 0 0 1.1em;
  text-wrap: pretty;
  text-align: justify;
  text-justify: inter-character;
  hanging-punctuation: allow-end;
}
.reader-body p:first-of-type::first-letter {
  font-family: var(--display);
  font-size: 2.6em;
  line-height: 1;
  float: left;
  padding: 4px 10px 0 0;
  color: var(--col-accent);
  font-weight: 500;
}
/* Tag — applies in both reader (essay) and gallery (OC) modals */
.reader-tag {
  font-family: var(--mono);
  font-size: 15px;
  line-height: 1.7;
  color: var(--col-accent);
  letter-spacing: .04em;
  margin-top: 32px;
  text-align: left;
  text-wrap: pretty;
}
.reader-tag::first-letter {
  font-size: 1em;
  float: none;
  padding: 0;
  color: var(--col-accent);
}

/* Aside callout — bracketed editorial detours like 「【插播一段...】」.
   Inset on both sides, smaller type, with a left rail in the collection accent. */
.reader-aside {
  margin: 28px -8px 28px 0;
  padding: 18px 22px 14px;
  border-left: 2px solid var(--col-accent);
  background: color-mix(in oklch, var(--col-accent) 4%, var(--bg-soft));
  position: relative;
}
.reader-aside::before {
  /* corner bracket — visual echo of 【 */
  content: "【";
  position: absolute; top: 6px; left: 8px;
  font-family: var(--display);
  font-size: 22px; line-height: 1;
  color: var(--col-accent);
  opacity: .55;
}
.reader-aside::after {
  content: "】";
  position: absolute; bottom: 4px; right: 10px;
  font-family: var(--display);
  font-size: 22px; line-height: 1;
  color: var(--col-accent);
  opacity: .55;
}
.reader-aside p {
  font-family: var(--display);
  font-size: 16.5px;
  line-height: 1.85;
  color: var(--fg-mute);
  margin: 0 0 0.9em;
  text-align: justify;
  text-justify: inter-character;
}
.reader-aside p:last-child { margin-bottom: 0; }
/* aside paragraphs should NOT get the drop-cap (it's only the first body paragraph) */
.reader-aside p::first-letter { float: none; font-size: inherit; padding: 0; color: inherit; font-weight: inherit; }

/* Poem block — parallel lines, slight indent, italic. */
.reader-poem {
  margin: 24px 0 28px;
  padding: 18px 24px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: color-mix(in oklch, var(--col-accent) 2%, transparent);
}
.reader-poem-line {
  font-family: var(--display);
  font-size: 17.5px;
  line-height: 1.75;
  color: var(--fg);
  font-style: italic;
  letter-spacing: 0.01em;
  text-align: center;
  text-wrap: balance;
}
.reader-poem-line:not(:last-child) {
  margin-bottom: 4px;
}

/* Litany block — left-aligned anaphora stanza ("她爱…她爱…").
   Same family as poem but prose-feeling: no italic, left aligned, hanging-indent for run-overs. */
.reader-litany {
  margin: 22px 0 26px;
  padding: 16px 0 16px 22px;
  border-left: 2px solid var(--col-accent);
}
.reader-litany-line {
  font-family: var(--display);
  font-size: 17px;
  line-height: 1.7;
  color: var(--fg);
  text-wrap: pretty;
  padding-left: 0;
  text-indent: -0.4em;  /* tiny hang for first char to align with rail */
  margin-bottom: 2px;
}
.reader-litany-line:last-child { margin-bottom: 0; }

/* Bulleted list — uses · (middle dot) markers as in the user's source text. */
.reader-list {
  margin: 18px 0 22px;
  padding: 0;
  list-style: none;
  display: flex; flex-direction: column;
  gap: 10px;
}
.reader-list li {
  font-family: var(--display);
  font-size: 17px;
  line-height: 1.75;
  color: var(--fg);
  position: relative;
  padding-left: 22px;
  text-wrap: pretty;
  text-align: justify;
  text-justify: inter-character;
}
.reader-list li::before {
  content: "·";
  position: absolute;
  left: 6px;
  top: -2px;
  font-size: 1.6em;
  line-height: 1;
  color: var(--col-accent);
  font-weight: 600;
}

/* Envoi — emphasized standalone closing line (a one-line crystallization of the piece) */
.reader-envoi {
  margin: 36px 0 !important;
  font-family: var(--display);
  font-size: 22px !important;
  line-height: 1.5 !important;
  font-weight: 500;
  color: var(--fg) !important;
  text-align: center !important;
  letter-spacing: 0.01em;
  padding: 18px 24px;
  border-top: 1px solid var(--col-accent);
  border-bottom: 1px solid var(--col-accent);
  position: relative;
  text-wrap: balance;
}
.reader-envoi::first-letter {
  float: none !important;
  font-size: inherit !important;
  padding: 0 !important;
  color: inherit !important;
}

/* Inline image-set — supporting evidence images (e.g. xhs screenshots). 
   Light grid embedded in the article body. */
.reader-image-set {
  display: grid;
  gap: 8px;
  margin: 24px 0 28px;
  padding: 12px;
  background: #000;
  border: 1px solid var(--border-strong);
}
.reader-image-cell {
  margin: 0;
  background: var(--bg-soft);
  overflow: hidden;
  aspect-ratio: 3 / 4;
  display: flex; align-items: center; justify-content: center;
}
.reader-image-cell img {
  width: 100%;
  height: 100%;
  object-fit: contain;   /* preserve framing — no crop */
  display: block;
}
.reader-image-set-cap {
  grid-column: 1 / -1;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--fg-mute);
  letter-spacing: .04em;
  padding: 6px 4px 0;
  text-align: center;
}

/* Section rule — discreet horizontal break between main essay and author note */.reader-rule {
  position: relative;
  height: 1px;
  margin: 44px 0;
  background: linear-gradient(90deg, transparent, var(--border-strong) 30%, var(--border-strong) 70%, transparent);
}
.reader-rule-glyph {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  background: var(--bg-soft);
  color: var(--col-accent);
  font-size: 14px;
  line-height: 1;
  padding: 0 10px;
}

/* Author note — labeled aside used for "作者自注" sections after the main essay */
.reader-note {
  margin: 24px 0 16px;
  padding: 18px 22px 8px;
  background: color-mix(in oklch, var(--col-accent) 5%, var(--paper));
  border: 1px solid var(--border);
  border-top: 2px solid var(--col-accent);
}
.reader-note-label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--col-accent);
  margin-bottom: 12px;
}
.reader-note p {
  font-family: var(--display);
  font-size: 15.5px;
  line-height: 1.75;
  color: var(--fg-mute);
  margin: 0 0 0.8em;
  text-align: justify;
  text-justify: inter-character;
}
.reader-note p:last-child { margin-bottom: 0; }
.reader-note p::first-letter { float: none; font-size: inherit; padding: 0; color: inherit; font-weight: inherit; }

/* Lead — opening paragraph styled bolder, no drop-cap, like a deck. */
.reader-lead {
  font-family: var(--display);
  font-size: 20px !important;
  line-height: 1.65 !important;
  color: var(--fg) !important;
  font-weight: 500;
  text-align: left !important;
  margin-bottom: 1.4em !important;
}
.reader-lead::first-letter {
  float: none !important;
  font-size: inherit !important;
  padding: 0 !important;
  color: var(--fg) !important;
}

.reader-foot {
  display: flex; align-items: center; gap: 14px;
  margin-top: 56px;
  color: var(--fg-faint);
}
.reader-foot-line {
  flex: 1;
  height: 1px;
  background: var(--border);
}
.reader-foot-mark {
  font-family: var(--display);
  font-size: 18px;
  color: var(--col-accent);
  letter-spacing: .04em;
}

/* ─────────────────────────────────────────────────────────────────
   GALLERY MODAL — OC 9-grid
   ───────────────────────────────────────────────────────────────── */

.gallery-shell {
  --col-accent: var(--accent);
  position: relative;
  width: 100%;
  max-width: 1080px;
  background: var(--bg-soft);
  border-left: 1px solid var(--border);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  animation: readerSlideUp .45s cubic-bezier(.2,.8,.2,1);
  box-shadow:
    0 -1px 0 var(--col-accent),
    0 24px 64px rgba(0,0,0,.45);
}

.gallery-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 32px;
}

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  max-width: 920px;
  margin: 0 auto;
}
/* Two-image variant — center the pair instead of stranding them in a 3-col row */
.gallery-grid:has(> .gallery-cell:nth-child(2):last-child) {
  grid-template-columns: repeat(2, minmax(0, 320px));
  justify-content: center;
  max-width: 680px;
}
/* Six-image variant — render as 2 columns × 3 rows for paired-comparison layouts */
.gallery-grid:has(> .gallery-cell:nth-child(6):last-child) {
  grid-template-columns: repeat(2, minmax(0, 360px));
  justify-content: center;
  max-width: 760px;
}

/* Gallery intro — short description above the 9-grid */
.gallery-intro {
  max-width: 640px;
  margin: 0 auto 28px;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--border);
}
.gallery-intro p {
  font-family: var(--display);
  font-size: 16px;
  line-height: 1.75;
  color: var(--fg);
  margin: 0 0 0.8em;
  text-wrap: pretty;
  text-align: justify;
  text-justify: inter-character;
}
.gallery-intro p:last-child { margin-bottom: 0; }
.gallery-intro p.reader-lead {
  font-size: 20px;
  font-weight: 500;
  text-align: left;
}

/* Gallery tag — hashtags under the 9-grid */
.gallery-tag {
  max-width: 920px;
  margin: 28px auto 0 !important;
  padding-top: 22px;
  border-top: 1px solid var(--border);
}

.gallery-cell {
  position: relative;
  aspect-ratio: 3 / 4;
  padding: 0;
  background: #000;
  border: 1px solid var(--border);
  cursor: pointer;
  overflow: hidden;
  transition: border-color .2s, transform .2s;
}
.gallery-cell:hover {
  border-color: var(--col-accent);
  transform: translateY(-1px);
}
.gallery-cell img {
  width: 100%; height: 100%;
  object-fit: contain;     /* letterbox if non-square — never crop */
  display: block;
}
.gallery-cell-num {
  position: absolute; top: 8px; left: 8px;
  font-family: var(--mono);
  font-size: 10px;
  padding: 2px 6px;
  background: color-mix(in oklch, var(--bg) 80%, transparent);
  color: var(--col-accent);
  letter-spacing: .04em;
}
.gallery-cell-cap {
  position: absolute; bottom: 0; left: 0; right: 0;
  font-family: var(--mono);
  font-size: 10px;
  padding: 6px 8px;
  background: linear-gradient(180deg, transparent 0%, rgba(0,0,0,.6) 100%);
  color: var(--fg);
  letter-spacing: .04em;
  opacity: 0;
  transition: opacity .2s;
}
.gallery-cell:hover .gallery-cell-cap { opacity: 1; }

/* Single-image carousel (Xiaohongshu-style) for posts with ≤3 images.
   One stage with prev/next chevrons + dot indicator — flipping through, not a grid. */
.gallery-carousel {
  max-width: 560px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
.gallery-car-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  padding: 0;
  background: #000;
  border: 1px solid var(--border);
  overflow: hidden;
  cursor: zoom-in;
  transition: border-color .2s;
}
.gallery-car-stage:hover { border-color: var(--col-accent); }
.gallery-car-stage img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.gallery-car-num {
  position: absolute;
  top: 10px; left: 10px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .04em;
  padding: 3px 8px;
  background: color-mix(in oklch, var(--bg) 80%, transparent);
  color: var(--col-accent);
  pointer-events: none;
}
.gallery-car-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in oklch, var(--bg) 78%, transparent);
  border: 1px solid var(--col-accent);
  color: var(--col-accent);
  font-size: 22px;
  font-family: var(--display);
  cursor: pointer;
  border-radius: 50%;
  user-select: none;
  transition: background .15s, color .15s, opacity .15s;
  opacity: 0;
}
.gallery-car-stage:hover .gallery-car-nav { opacity: 1; }
.gallery-car-nav:hover {
  background: var(--col-accent);
  color: var(--bg);
}
.gallery-car-prev { left: 10px; }
.gallery-car-next { right: 10px; }

.gallery-car-cap {
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.6;
  color: var(--muted);
  text-align: center;
  margin: 0;
  max-width: 480px;
  letter-spacing: .02em;
}
.gallery-car-dots {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: center;
}
.gallery-car-dot {
  width: 8px; height: 8px;
  padding: 0;
  border-radius: 50%;
  background: var(--border);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background .15s, transform .15s, border-color .15s;
}
.gallery-car-dot:hover { border-color: var(--col-accent); }
.gallery-car-dot.is-active {
  background: var(--col-accent);
  transform: scale(1.2);
}

/* ─── Split-view modal: image left, text right (XHS web style) ─── */
.gallery-shell-split {
  flex-direction: row;
  max-width: 1280px;
  height: min(86vh, 880px);
  padding: 0;
}
.gallery-shell-split .gallery-split-img {
  flex: 1 1 58%;
  min-width: 0;
  background: #0a0a0a;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 28px;
  border-right: 1px solid var(--border);
  position: relative;
}
.gallery-shell-split .gallery-carousel {
  width: 100%;
  height: 100%;
  max-width: none;
  justify-content: center;
}
.gallery-shell-split .gallery-car-stage {
  width: 100%;
  height: 100%;
  flex: 1;
  aspect-ratio: auto;
  background: transparent;
  border: none;
}
.gallery-shell-split .gallery-car-stage img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
/* Show navs more readily in the split view since there's room */
.gallery-shell-split .gallery-car-nav { opacity: .55; }
.gallery-shell-split .gallery-car-stage:hover .gallery-car-nav { opacity: 1; }
.gallery-shell-split .gallery-car-dots {
  position: absolute;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  padding: 6px 12px;
  background: color-mix(in oklch, #000 50%, transparent);
  border-radius: 999px;
  backdrop-filter: blur(8px);
}
.gallery-shell-split .gallery-car-dots .gallery-car-dot { background: rgba(255,255,255,.35); }
.gallery-shell-split .gallery-car-dots .gallery-car-dot.is-active { background: var(--col-accent); }

.gallery-shell-split .gallery-split-text {
  flex: 1 1 42%;
  min-width: 0;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  background: var(--bg-soft);
}
.gallery-split-head {
  flex: 0 0 auto;
  border-bottom: 1px solid var(--border);
}
.gallery-split-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 28px 30px 36px;
}
.gallery-split-title {
  font-family: var(--display);
  font-size: 24px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--fg);
  margin: 0 0 18px;
  text-wrap: pretty;
}
.gallery-split-active-cap {
  display: flex;
  gap: 10px;
  align-items: baseline;
  padding: 10px 12px;
  margin: 0 0 22px;
  background: color-mix(in oklch, var(--col-accent) 8%, transparent);
  border-left: 2px solid var(--col-accent);
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.55;
  color: var(--fg);
}
.gallery-split-active-num {
  color: var(--col-accent);
  letter-spacing: .04em;
  flex: 0 0 auto;
}
.gallery-split-body p {
  font-family: var(--display);
  font-size: 15px;
  line-height: 1.8;
  color: var(--fg);
  margin: 0 0 0.9em;
  text-wrap: pretty;
}
.gallery-split-body p.reader-lead {
  font-size: 17px;
  font-weight: 500;
  color: var(--fg);
  border-bottom: 1px solid var(--border);
  padding-bottom: 14px;
  margin-bottom: 18px;
}
.gallery-split-tag {
  margin-top: 24px !important;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}
.gallery-split-foot {
  margin-top: 24px;
  display: flex;
  align-items: center;
  gap: 12px;
}

@media (max-width: 880px) {
  .gallery-shell-split {
    flex-direction: column;
    height: 92vh;
  }
  .gallery-shell-split .gallery-split-img {
    flex: 0 0 52%;
    border-right: none;
    border-bottom: 1px solid var(--border);
    padding: 14px;
  }
  .gallery-shell-split .gallery-split-text {
    flex: 1 1 auto;
    max-width: none;
  }
  .gallery-split-scroll { padding: 18px 20px 28px; }
  .gallery-split-title { font-size: 20px; }
}

/* Lightbox (inside gallery modal) */
.lightbox {
  position: absolute; inset: 0;
  background: rgba(0, 0, 0, .82);
  backdrop-filter: blur(4px);
  z-index: 5;
  display: flex; align-items: center; justify-content: center;
  padding: 32px 64px;
  animation: readerFadeIn .2s ease;
}
.lightbox-fig {
  margin: 0;
  max-width: 720px;
  max-height: 100%;
  display: flex; flex-direction: column;
  background: #000;
  padding: 8px;
  border: 1px solid var(--col-accent);
}
.lightbox-fig img {
  display: block;
  width: 100%; height: auto;
  max-height: calc(100vh - 200px);
  object-fit: contain;
}
.lightbox-fig figcaption {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 10px 6px 4px;
  font-family: var(--mono); font-size: 12px;
  gap: 16px;
}
.lightbox-num { color: var(--col-accent); letter-spacing: .04em; }
.lightbox-cap { color: var(--fg); letter-spacing: .02em; }

.lightbox-nav {
  position: absolute;
  top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border: 1px solid var(--col-accent);
  color: var(--col-accent);
  font-size: 22px;
  font-family: var(--display);
  cursor: pointer;
  border-radius: 50%;
  transition: background .15s, color .15s;
}
.lightbox-nav:hover {
  background: var(--col-accent);
  color: var(--bg);
}
.lightbox-prev { left: 12px; }
.lightbox-next { right: 12px; }

@media (max-width: 720px) {
  .archive-collections { gap: 32px; }
  .archive-col { padding: 22px 4px 18px 16px; }
  .archive-col-name { font-size: 22px; }
  .archive-col-count { margin-left: 0; }
  .post-card { flex-basis: 160px; }

  .reader-article { padding: 36px 22px 80px; }
  .reader-body p { font-size: 16px; line-height: 1.8; }

  .gallery-scroll { padding: 18px; }
  .gallery-grid { gap: 8px; }
  .lightbox { padding: 12px; }
  .lightbox-prev { left: 4px; }
  .lightbox-next { right: 4px; }
}

@media (max-width: 720px) {
  .rpg-body { grid-template-columns: 1fr; }
  .rpg-portrait {
    flex-direction: row; align-items: center;
    border-right: 0; padding-right: 0; padding-bottom: 14px;
    border-bottom: 4px solid var(--rpg-fg-mute); margin-bottom: 14px;
  }
  .rpg-portrait-frame { width: 100px; height: 100px; aspect-ratio: auto; flex-shrink: 0; }
  .rpg-content { padding-left: 0; }
  .rpg-stat-row { grid-template-columns: 90px 1fr 36px; }
}
